]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-44449: faulthandler don't modify frame refcnt (GH-27850)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 30 Aug 2021 13:56:03 +0000 (06:56 -0700)
committerGitHub <noreply@github.com>
Mon, 30 Aug 2021 13:56:03 +0000 (06:56 -0700)
Fix a crash in the signal handler of the faulthandler module: no
longer modify the reference count of frame objects.
(cherry picked from commit fe997e1a67835a929705c8c305d41c4d7dd326e3)

Co-authored-by: Victor Stinner <vstinner@python.org>
Misc/NEWS.d/next/Library/2021-08-20-11-30-52.bpo-44449.1r2-lS.rst [new file with mode: 0644]
Python/traceback.c

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 (file)
index 0000000..52f0154
--- /dev/null
@@ -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.
index a9a9dd92e38ee9c9f7e14e867f7f6f47472ca97c..83f3074f43d05069e499b7fbdc21d87f051d222f 100644 (file)
@@ -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, "<no Python frame>\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;