Skip to content

Commit 0e42f0e

Browse files
committed
Backport r60104 + r60111 from trunk.
- Issue python#1336: fix a race condition in subprocess.Popen if the garbage collector kicked in at the wrong time that would cause the process to hang when the child wrote to stderr.
1 parent 80ebe95 commit 0e42f0e

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

Lib/subprocess.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ class Popen(args, bufsize=0, executable=None,
346346
import os
347347
import types
348348
import traceback
349+
import gc
349350

350351
if mswindows:
351352
import threading
@@ -899,7 +900,16 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
899900
errpipe_read, errpipe_write = os.pipe()
900901
self._set_cloexec_flag(errpipe_write)
901902

902-
self.pid = os.fork()
903+
gc_was_enabled = gc.isenabled()
904+
# Disable gc to avoid bug where gc -> file_dealloc ->
905+
# write to stderr -> hang. http://bugs.python.org/issue1336
906+
gc.disable()
907+
try:
908+
self.pid = os.fork()
909+
except:
910+
if gc_was_enabled:
911+
gc.enable()
912+
raise
903913
if self.pid == 0:
904914
# Child
905915
try:
@@ -958,6 +968,8 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
958968
os._exit(255)
959969

960970
# Parent
971+
if gc_was_enabled:
972+
gc.enable()
961973
os.close(errpipe_write)
962974
if p2cread and p2cwrite:
963975
os.close(p2cread)

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ Extension Modules
2626
Library
2727
-------
2828

29+
- Issue #1336: fix a race condition in subprocess.Popen if the garbage
30+
collector kicked in at the wrong time that would cause the process
31+
to hang when the child wrote to stderr.
32+
2933
- Bug #1728403: Fix a bug that CJKCodecs StreamReader hangs when it
3034
reads a file that ends with incomplete sequence and sizehint argument
3135
for .read() is specified.

0 commit comments

Comments
 (0)