diff --git a/Misc/NEWS.d/next/Library/2021-08-20-11-30-52.bpo-44449.1r2-lS.rst b/Misc/NEWS.d/next/Library/2021-08-20-11-30-52.bpo-44449.1r2-lS.rst new file mode 100644 index 00000000000000..52f01541fca6a7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-08-20-11-30-52.bpo-44449.1r2-lS.rst @@ -0,0 +1,2 @@ +Fix a crash in the signal handler of the :mod:`faulthandler` module: no +longer modify the reference count of frame objects. Patch by Victor Stinner. diff --git a/Python/traceback.c b/Python/traceback.c index a9a9dd92e38ee9..83f3074f43d050 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -799,7 +799,10 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) PUTS(fd, "Stack (most recent call first):\n"); } - frame = PyThreadState_GetFrame(tstate); + // Use a borrowed reference. Avoid Py_INCREF/Py_DECREF, since this function + // can be called in a signal handler by the faulthandler module which must + // not modify Python objects. + frame = tstate->frame; if (frame == NULL) { PUTS(fd, "\n"); return; @@ -808,17 +811,14 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) depth = 0; while (1) { if (MAX_FRAME_DEPTH <= depth) { - Py_DECREF(frame); PUTS(fd, " ...\n"); break; } if (!PyFrame_Check(frame)) { - Py_DECREF(frame); break; } dump_frame(fd, frame); - PyFrameObject *back = PyFrame_GetBack(frame); - Py_DECREF(frame); + PyFrameObject *back = frame->f_back; if (back == NULL) { break;