https://github.com/python/cpython/commit/75de39ba1b61636e4a49a457de23de78e7f0a5a1
commit: 75de39ba1b61636e4a49a457de23de78e7f0a5a1
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: colesbury <[email protected]>
date: 2025-10-07T18:11:46Z
summary:

[3.14] gh-137185: Fix `_Py_DumpStack()` async signal safety (gh-137187) 
(gh-137206)

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 <[email protected]>

files:
A Misc/NEWS.d/next/Library/2025-07-28-20-48-32.gh-issue-137185.fgI7-B.rst
M Include/internal/pycore_traceback.h
M Modules/faulthandler.c
M Python/traceback.c

diff --git a/Include/internal/pycore_traceback.h 
b/Include/internal/pycore_traceback.h
index d71dd2886999a6..a4f125e073d3d1 100644
--- a/Include/internal/pycore_traceback.h
+++ b/Include/internal/pycore_traceback.h
@@ -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
index 00000000000000..89398dff147394
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-07-28-20-48-32.gh-issue-137185.fgI7-B.rst
@@ -0,0 +1,2 @@
+Fix a potential async-signal-safety issue in :mod:`faulthandler` when
+printing C stack traces.
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index d49ce794d88674..2495faa38170b7 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -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;
diff --git a/Python/traceback.c b/Python/traceback.c
index f3c5644aeb1799..11e52936f309ca 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -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
+}

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to