diff -r a7406565ef1c Lib/multiprocessing/forking.py --- a/Lib/multiprocessing/forking.py Tue Jan 24 09:05:18 2012 +0100 +++ b/Lib/multiprocessing/forking.py Tue Jan 24 10:32:37 2012 +0100 @@ -129,8 +129,6 @@ import random random.seed() code = process_obj._bootstrap() - sys.stdout.flush() - sys.stderr.flush() os._exit(code) # `w` will be closed when the child exits, at which point `r` diff -r a7406565ef1c Lib/multiprocessing/process.py --- a/Lib/multiprocessing/process.py Tue Jan 24 09:05:18 2012 +0100 +++ b/Lib/multiprocessing/process.py Tue Jan 24 10:32:37 2012 +0100 @@ -291,16 +291,17 @@ exitcode = e.args[0] else: sys.stderr.write(e.args[0] + '\n') - sys.stderr.flush() exitcode = 1 except: exitcode = 1 import traceback sys.stderr.write('Process %s:\n' % self.name) + traceback.print_exc() + finally: + util.info('process exiting with exitcode %d' % exitcode) + sys.stdout.flush() sys.stderr.flush() - traceback.print_exc() - util.info('process exiting with exitcode %d' % exitcode) return exitcode # diff -r a7406565ef1c Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py Tue Jan 24 09:05:18 2012 +0100 +++ b/Lib/test/test_multiprocessing.py Tue Jan 24 10:32:37 2012 +0100 @@ -378,6 +378,29 @@ p.join() self.assertTrue(wait_for_handle(sentinel, timeout=DELTA)) + def test_stderr_flush(self): + # sys.stderr is flushed at process shutdown (issue #13812) + if self.TYPE == "threads": + return + + testfn = test.support.TESTFN + self.addCleanup(test.support.unlink, testfn) + proc = self.Process(target=self._test_stderr_flush, args=(testfn,)) + proc.start() + proc.join() + with open(testfn, 'r') as f: + err = f.read() + # The whole traceback was printed + self.assertIn("ZeroDivisionError", err) + self.assertIn("test_multiprocessing.py", err) + self.assertIn("1/0 # MARKER", err) + + @classmethod + def _test_stderr_flush(cls, testfn): + sys.stderr = open(testfn, 'w') + 1/0 # MARKER + + # # #