]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-137185: Fix `_Py_DumpStack()` async signal safety (gh-137187)
authorSam Gross <colesbury@gmail.com>
Tue, 29 Jul 2025 14:25:32 +0000 (10:25 -0400)
committerGitHub <noreply@github.com>
Tue, 29 Jul 2025 14:25:32 +0000 (14:25 +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.

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 73bea8172c7253dbdea92b9e4b748346f7855e53..84cfc6bd8ef6e491dda381cfd58d6bc74f25ee5d 100644 (file)
@@ -524,6 +524,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 4f674eaf55715b024e9e3970994a8b3d2d4717db..da7956d1ec47b4e1ae579b60a2e29a3cbaf67b65 100644 (file)
@@ -1326,3 +1326,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
+}