changeset: 76066:8609d7fcdcc7 branch: 2.7 parent: 76049:d3a82a26c705 user: Benjamin Peterson date: Mon Apr 02 11:15:17 2012 -0400 files: Lib/test/test_thread.py Misc/NEWS Modules/threadmodule.c description: prevent writing to stderr from messing up the exception state (closes #14474) diff -r d3a82a26c705 -r 8609d7fcdcc7 Lib/test/test_thread.py --- a/Lib/test/test_thread.py Sun Apr 01 16:05:46 2012 +0200 +++ b/Lib/test/test_thread.py Mon Apr 02 11:15:17 2012 -0400 @@ -130,6 +130,30 @@ time.sleep(0.01) self.assertEqual(thread._count(), orig) + def test_save_exception_state_on_error(self): + # See issue #14474 + def task(): + started.release() + sys.stderr = stderr + raise SyntaxError + def mywrite(self, *args): + try: + raise ValueError + except ValueError: + pass + real_write(self, *args) + c = thread._count() + started = thread.allocate_lock() + with test_support.captured_output("stderr") as stderr: + real_write = stderr.write + stderr.write = mywrite + started.acquire() + thread.start_new_thread(task, ()) + started.acquire() + while thread._count()> c: + pass + self.assertIn("Traceback", stderr.getvalue()) + class Barrier: def __init__(self, num_threads): diff -r d3a82a26c705 -r 8609d7fcdcc7 Misc/NEWS --- a/Misc/NEWS Sun Apr 01 16:05:46 2012 +0200 +++ b/Misc/NEWS Mon Apr 02 11:15:17 2012 -0400 @@ -9,6 +9,9 @@ Core and Builtins ----------------- +- Issue #14474: Save and restore exception state in thread.start_new_thread() + while writing error message if the thread leaves a unhandled exception. + - Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch by Suman Saha. diff -r d3a82a26c705 -r 8609d7fcdcc7 Modules/threadmodule.c --- a/Modules/threadmodule.c Sun Apr 01 16:05:46 2012 +0200 +++ b/Modules/threadmodule.c Mon Apr 02 11:15:17 2012 -0400 @@ -618,6 +618,8 @@ PyErr_Clear(); else { PyObject *file; + PyObject *exc, *value, *tb; + PyErr_Fetch(&exc, &value, &tb); PySys_WriteStderr( "Unhandled exception in thread started by "); file = PySys_GetObject("stderr"); @@ -625,6 +627,7 @@ PyFile_WriteObject(boot->func, file, 0); else PyObject_Print(boot->func, stderr, 0); + PyErr_Restore(exc, value, tb); PySys_WriteStderr("\n"); PyErr_PrintEx(0); }

AltStyle によって変換されたページ (->オリジナル) /