https://github.com/python/cpython/commit/11a8652e25341e696b06d8dc7a18e8c3ee8059e4
commit: 11a8652e25341e696b06d8dc7a18e8c3ee8059e4
branch: main
author: Sam Gross <colesb...@gmail.com>
committer: colesbury <colesb...@gmail.com>
date: 2025-07-29T14:25:32Z
summary:

gh-137185: Fix `_Py_DumpStack()` async signal safety (gh-137187)

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.

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 73bea8172c7253..84cfc6bd8ef6e4 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -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;
diff --git a/Python/traceback.c b/Python/traceback.c
index 4f674eaf55715b..da7956d1ec47b4 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -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
+}

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: arch...@mail-archive.com

Reply via email to