Skip to content

Commit

Permalink
pythongh-102056: Fix a few bugs in error handling of exception printi…
Browse files Browse the repository at this point in the history
…ng code (python#102078)
  • Loading branch information
iritkatriel authored and python-sidebar committed Sep 1, 2024
1 parent 7852ee7 commit 8a85303
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
31 changes: 31 additions & 0 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -1523,6 +1523,37 @@ def run():
self.assertEqual(out, b'')
self.assertNotIn("Unhandled exception", err.decode())

def test_print_exception_gh_102056(self):
# This used to crash. See gh-102056.
script = r"""if True:
import time
import threading
import _thread
def f():
try:
f()
except RecursionError:
f()
def g():
try:
raise ValueError()
except* ValueError:
f()
def h():
time.sleep(1)
_thread.interrupt_main()
t = threading.Thread(target=h)
t.start()
g()
t.join()
"""

assert_python_failure("-c", script)

def test_bare_raise_in_brand_new_thread(self):
def bare_raise():
raise
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix error handling bugs in interpreter's exception printing code, which could cause a crash on infinite recursion.
23 changes: 16 additions & 7 deletions Python/pythonrun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,8 +1246,7 @@ print_chained(struct exception_print_context* ctx, PyObject *value,
const char * message, const char *tag)
{
PyObject *f = ctx->file;

if (_Py_EnterRecursiveCall(" in print_chained") < 0) {
if (_Py_EnterRecursiveCall(" in print_chained")) {
return -1;
}
bool need_close = ctx->need_close;
Expand Down Expand Up @@ -1374,7 +1373,9 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
if (ctx->exception_group_depth == 0) {
ctx->exception_group_depth += 1;
}
print_exception(ctx, value);
if (print_exception(ctx, value) < 0) {
return -1;
}

PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs;
assert(excs && PyTuple_Check(excs));
Expand Down Expand Up @@ -1424,7 +1425,7 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
PyObject *exc = PyTuple_GET_ITEM(excs, i);

if (!truncated) {
if (_Py_EnterRecursiveCall(" in print_exception_group") != 0) {
if (_Py_EnterRecursiveCall(" in print_exception_group")) {
return -1;
}
int res = print_exception_recursive(ctx, exc);
Expand Down Expand Up @@ -1477,22 +1478,30 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
static int
print_exception_recursive(struct exception_print_context *ctx, PyObject *value)
{
if (_Py_EnterRecursiveCall(" in print_exception_recursive")) {
return -1;
}
if (ctx->seen != NULL) {
/* Exception chaining */
if (print_exception_cause_and_context(ctx, value) < 0) {
return -1;
goto error;
}
}
if (!_PyBaseExceptionGroup_Check(value)) {
if (print_exception(ctx, value) < 0) {
return -1;
goto error;
}
}
else if (print_exception_group(ctx, value) < 0) {
return -1;
goto error;
}
assert(!PyErr_Occurred());

_Py_LeaveRecursiveCall();
return 0;
error:
_Py_LeaveRecursiveCall();
return -1;
}

#define PyErr_MAX_GROUP_WIDTH 15
Expand Down

0 comments on commit 8a85303

Please sign in to comment.