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 <rep...@bugs.python.org>
<http://bugs.python.org/issue26731>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to