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

Skip to content

Commit e900096

Browse files
committed
prevent writing to stderr from messing up the exception state (closes #14474)
1 parent b6af60c commit e900096

3 files changed

Lines changed: 30 additions & 0 deletions

File tree

Lib/test/test_thread.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,30 @@ def task():
128128
time.sleep(0.01)
129129
self.assertEqual(thread._count(), orig)
130130

131+
def test_save_exception_state_on_error(self):
132+
# See issue #14474
133+
def task():
134+
started.release()
135+
sys.stderr = stderr
136+
raise SyntaxError
137+
def mywrite(self, *args):
138+
try:
139+
raise ValueError
140+
except ValueError:
141+
pass
142+
real_write(self, *args)
143+
c = thread._count()
144+
started = thread.allocate_lock()
145+
with support.captured_output("stderr") as stderr:
146+
real_write = stderr.write
147+
stderr.write = mywrite
148+
started.acquire()
149+
thread.start_new_thread(task, ())
150+
started.acquire()
151+
while thread._count() > c:
152+
pass
153+
self.assertIn("Traceback", stderr.getvalue())
154+
131155

132156
class Barrier:
133157
def __init__(self, num_threads):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.2.4
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #14474: Save and restore exception state in thread.start_new_thread()
14+
while writing error message if the thread leaves a unhandled exception.
15+
1316
- Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch
1417
by Suman Saha.
1518

Modules/_threadmodule.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,17 @@ t_bootstrap(void *boot_raw)
994994
PyErr_Clear();
995995
else {
996996
PyObject *file;
997+
PyObject *exc, *value, *tb;
997998
PySys_WriteStderr(
998999
"Unhandled exception in thread started by ");
1000+
PyErr_Fetch(&exc, &value, &tb);
9991001
file = PySys_GetObject("stderr");
10001002
if (file != NULL && file != Py_None)
10011003
PyFile_WriteObject(boot->func, file, 0);
10021004
else
10031005
PyObject_Print(boot->func, stderr, 0);
10041006
PySys_WriteStderr("\n");
1007+
PyErr_Restore(exc, value, tb);
10051008
PyErr_PrintEx(0);
10061009
}
10071010
}

0 commit comments

Comments
 (0)