subprocess: Fix waitpid() semantics. Occasionally waitpid() may return (0,0) even if WNOHANG is not specified. This behavior is currently not handled by the the wait() method, which is executed in many code paths assuming that it will properly collect the child's return status. If this isn't fixed, long-lived python processes may end up collecting zombie children under certain conditions. Signed-off-by: Adin Scannell diff -r d46c1973d3c4 Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1286,7 +1286,7 @@ class Popen(object): def wait(self): """Wait for child process to terminate. Returns returncode attribute.""" - if self.returncode is None: + while self.returncode is None: try: pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) except OSError as e: @@ -1295,8 +1295,10 @@ class Popen(object): # This happens if SIGCLD is set to be ignored or waiting # for child processes has otherwise been disabled for our # process. This child is dead, we can't get the status. + pid = self.pid sts = 0 - self._handle_exitstatus(sts) + if pid == self.pid: + self._handle_exitstatus(sts) return self.returncode