prevent writing to stderr from messing up the exception state (closes #14474)

This commit is contained in:
Benjamin Peterson 2012-04-02 11:15:17 -04:00
parent fe9417726c
commit f73813a8bb
3 changed files with 30 additions and 0 deletions

View File

@ -130,6 +130,30 @@ class ThreadRunningTests(BasicThreadTest):
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):

View File

@ -9,6 +9,9 @@ What's New in Python 2.7.4
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.

View File

@ -618,6 +618,8 @@ t_bootstrap(void *boot_raw)
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 @@ t_bootstrap(void *boot_raw)
PyFile_WriteObject(boot->func, file, 0);
else
PyObject_Print(boot->func, stderr, 0);
PyErr_Restore(exc, value, tb);
PySys_WriteStderr("\n");
PyErr_PrintEx(0);
}