Author eryksun
Recipients Leonardo Francalanci, eryksun, martin.panter, r.david.murray
Date 2017-09-13.23:11:33
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1505344293.84.0.126760114353.issue31447@psf.upfronthosting.co.za>
In-reply-to
Content
> the process terminates, but "communicate" doesn't exit. It doesn't 
> say "communicate will hang as long as the pipes are open".

I think the problem with leaked handles does warrant a note. It can be a difficult problem to diagnose otherwise.

If communicate() raises subprocess.TimeoutExpired, it can be called again after the caller takes whatever action is necessary to resolve the problem, such as killing a process group as proposed by issue 5115.

> the "python.exe" process doesn't actually timeout!!! It just exits 
> (with exception, but that's not important), and I would like to get
> the error from stderr! While I can't get it because "communicate" 
> raises an exception...

subprocess.run() in the child does time out and raise subprocess.TimeoutExpired. For the parent to read stdout and stderr to EOF, all pipe handles with write access have to close. Calling communicate() again will succeed once waitfor.exe either exits or gets terminated. 

Since python.exe and waitfor.exe are console processes, and waitfor.exe inherits Python's console, you can send it a Ctrl+Break event to make it exit. Make sure to create a new process group in the Popen() call by passing the argument creationflags=subprocess.CREATE_NEW_PROCESS_GROUP. Then to deal with a timeout, call proc.send_signal(signal.CTRL_BREAK_EVENT) and retry communicate(). 

(Yes, it's wrong that send_signal sends Ctrl+Break to a process group instead of explicitly requiring a `group` argument to enable this, as proposed in issue 5115. I guess whoever implemented os.kill for Windows didn't understand that GenerateConsoleCtrlEvent should have been used to implement os.killpg instead.)

> I don't care what the called process does. 

If you have source control of the child process and don't care about the output of grandchild processes, redirect their standard I/O to the NUL device. Also, make the child's standard I/O files non-inheritable, or if you're using C/C++, call CreateProcess with a PROC_THREAD_ATTRIBUTE_HANDLE_LIST to control handle inheritance (this should be available in Python 3.7, pending issue 19764).
History
Date User Action Args
2017-09-13 23:11:33eryksunsetrecipients: + eryksun, r.david.murray, martin.panter, Leonardo Francalanci
2017-09-13 23:11:33eryksunsetmessageid: <1505344293.84.0.126760114353.issue31447@psf.upfronthosting.co.za>
2017-09-13 23:11:33eryksunlinkissue31447 messages
2017-09-13 23:11:33eryksuncreate