Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d843d2

Browse files
committed
Issue #13812: When a multiprocessing Process child raises an exception, flush stderr after printing the exception traceback.
2 parents e10ae88 + 84a0fbf commit 2d843d2

4 files changed

Lines changed: 30 additions & 5 deletions

File tree

Lib/multiprocessing/forking.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ def __init__(self, process_obj):
129129
import random
130130
random.seed()
131131
code = process_obj._bootstrap()
132-
sys.stdout.flush()
133-
sys.stderr.flush()
134132
os._exit(code)
135133

136134
# `w` will be closed when the child exits, at which point `r`

Lib/multiprocessing/process.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,17 @@ def _bootstrap(self):
291291
exitcode = e.args[0]
292292
else:
293293
sys.stderr.write(e.args[0] + '\n')
294-
sys.stderr.flush()
295294
exitcode = 1
296295
except:
297296
exitcode = 1
298297
import traceback
299298
sys.stderr.write('Process %s:\n' % self.name)
300-
sys.stderr.flush()
301299
traceback.print_exc()
300+
finally:
301+
util.info('process exiting with exitcode %d' % exitcode)
302+
sys.stdout.flush()
303+
sys.stderr.flush()
302304

303-
util.info('process exiting with exitcode %d' % exitcode)
304305
return exitcode
305306

306307
#

Lib/test/test_multiprocessing.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,29 @@ def test_subclassing(self):
417417
uppercaser.stop()
418418
uppercaser.join()
419419

420+
def test_stderr_flush(self):
421+
# sys.stderr is flushed at process shutdown (issue #13812)
422+
if self.TYPE == "threads":
423+
return
424+
425+
testfn = test.support.TESTFN
426+
self.addCleanup(test.support.unlink, testfn)
427+
proc = self.Process(target=self._test_stderr_flush, args=(testfn,))
428+
proc.start()
429+
proc.join()
430+
with open(testfn, 'r') as f:
431+
err = f.read()
432+
# The whole traceback was printed
433+
self.assertIn("ZeroDivisionError", err)
434+
self.assertIn("test_multiprocessing.py", err)
435+
self.assertIn("1/0 # MARKER", err)
436+
437+
@classmethod
438+
def _test_stderr_flush(cls, testfn):
439+
sys.stderr = open(testfn, 'w')
440+
1/0 # MARKER
441+
442+
420443
#
421444
#
422445
#

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ Core and Builtins
461461
Library
462462
-------
463463

464+
- Issue #13812: When a multiprocessing Process child raises an exception,
465+
flush stderr after printing the exception traceback.
466+
464467
- Issue #13885: CVE-2011-3389: the _ssl module would always disable the CBC
465468
IV attack countermeasure.
466469

0 commit comments

Comments
 (0)