]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-137185: Fix `_Py_DumpStack()` async signal safety (gh-137187) (gh-137206)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 7 Oct 2025 18:11:46 +0000 (20:11 +0200)
committerGitHub <noreply@github.com>
Tue, 7 Oct 2025 18:11:46 +0000 (18:11 +0000)
Call backtrace() once when installing the signal handler to ensure that
libgcc is dynamically loaded outside the signal handler.

This fixes a "signal-unsafe call inside of a signal" TSan error from
test_faulthandler.test_enable_fd.
(cherry picked from commit 11a8652e25341e696b06d8dc7a18e8c3ee8059e4)

Co-authored-by: Sam Gross <colesbury@gmail.com>
Include/internal/pycore_traceback.h
Misc/NEWS.d/next/Library/2025-07-28-20-48-32.gh-issue-137185.fgI7-B.rst [new file with mode: 0644]
Modules/faulthandler.c
Python/traceback.c

index d71dd2886999a6cbb2c6c85b92b46e37ecb34f22..a4f125e073d3d1dbfdb548ce9c6e268648afb812 100644 (file)
@@ -100,6 +100,7 @@ extern int _Py_WriteIndentedMargin(int, const char*, PyObject *);
 extern int _Py_WriteIndent(int, PyObject *);
 
 // Export for the faulthandler module
+PyAPI_FUNC(void) _Py_InitDumpStack(void);
 PyAPI_FUNC(void) _Py_DumpStack(int fd);
 
 #ifdef __cplusplus
diff --git a/Misc/NEWS.d/next/Library/2025-07-28-20-48-32.gh-issue-137185.fgI7-B.rst b/Misc/NEWS.d/next/Library/2025-07-28-20-48-32.gh-issue-137185.fgI7-B.rst
new file mode 100644 (file)
index 0000000..89398df
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a potential async-signal-safety issue in :mod:`faulthandler` when
+printing C stack traces.
index d49ce794d886745ea519ca4a44e4506f08d73d6c..2495faa38170b79b3ae07d0e258ffe5daba02a07 100644 (file)
@@ -525,6 +525,11 @@ faulthandler_enable(void)
     }
 #endif
 
+    // gh-137185: Initialize C stack trace dumping outside of the signal
+    // handler. Specifically, we call backtrace() to ensure that libgcc is
+    // dynamically loaded outside of the signal handler.
+    _Py_InitDumpStack();
+
     for (size_t i=0; i < faulthandler_nsignals; i++) {
         fault_handler_t *handler;
         int err;
index f3c5644aeb17990bf3dfc0f535cb5adc3543be58..11e52936f309caa77938ac4f68d94a2fa58bb3a3 100644 (file)
@@ -1327,3 +1327,13 @@ _Py_DumpStack(int fd)
     PUTS(fd, "  <cannot get C stack on this system>\n");
 }
 #endif
+
+void
+_Py_InitDumpStack(void)
+{
+#ifdef CAN_C_BACKTRACE
+    // gh-137185: Call backtrace() once to force libgcc to be loaded early.
+    void *callstack[1];
+    (void)backtrace(callstack, 1);
+#endif
+}