mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
gh-102056: Fix a few bugs in error handling of exception printing code (#102078)
This commit is contained in:
parent
4d3bc89a3f
commit
022b44f254
3 changed files with 48 additions and 7 deletions
|
@ -1523,6 +1523,37 @@ class ThreadingExceptionTests(BaseTestCase):
|
||||||
self.assertEqual(out, b'')
|
self.assertEqual(out, b'')
|
||||||
self.assertNotIn("Unhandled exception", err.decode())
|
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 test_bare_raise_in_brand_new_thread(self):
|
||||||
def bare_raise():
|
def bare_raise():
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix error handling bugs in interpreter's exception printing code, which could cause a crash on infinite recursion.
|
|
@ -1246,8 +1246,7 @@ print_chained(struct exception_print_context* ctx, PyObject *value,
|
||||||
const char * message, const char *tag)
|
const char * message, const char *tag)
|
||||||
{
|
{
|
||||||
PyObject *f = ctx->file;
|
PyObject *f = ctx->file;
|
||||||
|
if (_Py_EnterRecursiveCall(" in print_chained")) {
|
||||||
if (_Py_EnterRecursiveCall(" in print_chained") < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bool need_close = ctx->need_close;
|
bool need_close = ctx->need_close;
|
||||||
|
@ -1374,7 +1373,9 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
|
||||||
if (ctx->exception_group_depth == 0) {
|
if (ctx->exception_group_depth == 0) {
|
||||||
ctx->exception_group_depth += 1;
|
ctx->exception_group_depth += 1;
|
||||||
}
|
}
|
||||||
print_exception(ctx, value);
|
if (print_exception(ctx, value) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs;
|
PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs;
|
||||||
assert(excs && PyTuple_Check(excs));
|
assert(excs && PyTuple_Check(excs));
|
||||||
|
@ -1424,7 +1425,7 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
|
||||||
PyObject *exc = PyTuple_GET_ITEM(excs, i);
|
PyObject *exc = PyTuple_GET_ITEM(excs, i);
|
||||||
|
|
||||||
if (!truncated) {
|
if (!truncated) {
|
||||||
if (_Py_EnterRecursiveCall(" in print_exception_group") != 0) {
|
if (_Py_EnterRecursiveCall(" in print_exception_group")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int res = print_exception_recursive(ctx, exc);
|
int res = print_exception_recursive(ctx, exc);
|
||||||
|
@ -1477,22 +1478,30 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
|
||||||
static int
|
static int
|
||||||
print_exception_recursive(struct exception_print_context *ctx, PyObject *value)
|
print_exception_recursive(struct exception_print_context *ctx, PyObject *value)
|
||||||
{
|
{
|
||||||
|
if (_Py_EnterRecursiveCall(" in print_exception_recursive")) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (ctx->seen != NULL) {
|
if (ctx->seen != NULL) {
|
||||||
/* Exception chaining */
|
/* Exception chaining */
|
||||||
if (print_exception_cause_and_context(ctx, value) < 0) {
|
if (print_exception_cause_and_context(ctx, value) < 0) {
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_PyBaseExceptionGroup_Check(value)) {
|
if (!_PyBaseExceptionGroup_Check(value)) {
|
||||||
if (print_exception(ctx, value) < 0) {
|
if (print_exception(ctx, value) < 0) {
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (print_exception_group(ctx, value) < 0) {
|
else if (print_exception_group(ctx, value) < 0) {
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
assert(!PyErr_Occurred());
|
assert(!PyErr_Occurred());
|
||||||
|
|
||||||
|
_Py_LeaveRecursiveCall();
|
||||||
return 0;
|
return 0;
|
||||||
|
error:
|
||||||
|
_Py_LeaveRecursiveCall();
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PyErr_MAX_GROUP_WIDTH 15
|
#define PyErr_MAX_GROUP_WIDTH 15
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue