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.
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
--- /dev/null
+Fix a potential async-signal-safety issue in :mod:`faulthandler` when
+printing C stack traces.
}
#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;
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
+}