New submission from Matt Peters:
Tested in on Windows 8.1 with python 2.7.5.
I have a parent process that creates a child process and calls communicate to
get stdout/stderr from the child. The child process calls a persistent
process, with stdout/stderr/stdin set to os.devnull, and then exits without
waiting on the child process. Sample code is below.
The child process exits successfully, but communicate on the the parent process
does not return until the persistent process is terminated. Expected behavior
is that the child process closes its stdout/stderr pipes on exit, and those
pipes are not open anywhere else, so the parent process returns from
communicate once the child process exits.
One fix that stops the bug from manifesting is to edit subprocess.py:954 and
pass in FALSE for inherit_handles in the call to _subprocess.CreateProcess
rather than passing in int(not close_fds). With the current code there is no
way for the user of subprocess to trigger this behavior, because close_fds is
necessarily False when redirecting stdout/stderr/stdin due to an exception
raised in the Popen constructor.
I believe the proper fix to set close_fds to True, and pass in the handles
through startupinfo, if any one of the pipes has been redirected. This will
require some changes to _get_handles and some significant testing.
A workaround fix that is easier to implement is to remove the assertion in the
Popen constructor and allow the caller to specify close_fds=True even when
redirecting one of the inputs.
Test case:
Three programs: parent.py, child.py, and persistent.py.
Launch parent.py.
Behavior:
child.py returns immediately
resident.py exits after 10 seconds
parent.py prints its output and exits immediately after resident.py exits
Expected Behavior:
child.py returns immediately
parent.py prints its output and exits immediately after child.py exits
resident.py exits after 10 seconds
############### parent.py ##########################
import subprocess
proc = subprocess.Popen("python child.py", stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
(output, error) = proc.communicate()
print 'parent complete'
############### child.py ###########################
import os
import subprocess
with open(os.devnull, 'w') as devnull:
proc = subprocess.Popen('python resident.py', stdout=devnull,
stderr=devnull, stdin=devnull)
############### resident.py ########################
import time
time.sleep(10)
----------
components: Windows
messages: 263149
nosy: paul.moore, saifujinaro, steve.dower, tim.golden, zach.ware
priority: normal
severity: normal
status: open
title: subprocess on windows leaks stdout/stderr handle to child process when
stdout/stderr overridden
versions: Python 2.7
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue26731>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com