https://github.com/python/cpython/commit/c9356feef28e6dfc4dc32830d3427a5ae0e426e2
commit: c9356feef28e6dfc4dc32830d3427a5ae0e426e2
branch: main
author: Peter Bierma <[email protected]>
committer: colesbury <[email protected]>
date: 2025-01-02T13:56:01-05:00
summary:
gh-128400: Stop-the-world when manually calling `faulthandler` (GH-128422)
files:
A Misc/NEWS.d/next/Library/2025-01-02-13-05-16.gh-issue-128400.5N43fF.rst
M Lib/test/test_faulthandler.py
M Modules/faulthandler.c
diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py
index 60815be96e14eb..fd56dee5d842ac 100644
--- a/Lib/test/test_faulthandler.py
+++ b/Lib/test/test_faulthandler.py
@@ -7,7 +7,7 @@
import subprocess
import sys
from test import support
-from test.support import os_helper, script_helper, is_android, MS_WINDOWS
+from test.support import os_helper, script_helper, is_android, MS_WINDOWS,
threading_helper
import tempfile
import unittest
from textwrap import dedent
@@ -896,6 +896,34 @@ def test_cancel_later_without_dump_traceback_later(self):
self.assertEqual(output, [])
self.assertEqual(exitcode, 0)
+ @threading_helper.requires_working_threading()
+ @unittest.skipUnless(support.Py_GIL_DISABLED, "only meaningful if the GIL
is disabled")
+ def test_free_threaded_dump_traceback(self):
+ # gh-128400: Other threads need to be paused to invoke faulthandler
+ code = dedent("""
+ import faulthandler
+ from threading import Thread, Event
+
+ class Waiter(Thread):
+ def __init__(self):
+ Thread.__init__(self)
+ self.running = Event()
+ self.stop = Event()
+
+ def run(self):
+ self.running.set()
+ self.stop.wait()
+
+ for _ in range(100):
+ waiter = Waiter()
+ waiter.start()
+ waiter.running.wait()
+ faulthandler.dump_traceback(all_threads=True)
+ waiter.stop.set()
+ waiter.join()
+ """)
+ _, exitcode = self.get_output(code)
+ self.assertEqual(exitcode, 0)
if __name__ == "__main__":
unittest.main()
diff --git
a/Misc/NEWS.d/next/Library/2025-01-02-13-05-16.gh-issue-128400.5N43fF.rst
b/Misc/NEWS.d/next/Library/2025-01-02-13-05-16.gh-issue-128400.5N43fF.rst
new file mode 100644
index 00000000000000..4033dea4eaf7bf
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-01-02-13-05-16.gh-issue-128400.5N43fF.rst
@@ -0,0 +1,2 @@
+Fix crash when using :func:`faulthandler.dump_traceback` while other threads
+are active on the :term:`free threaded <free threading>` build.
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index b62362f277797e..2d16028a5232d0 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -237,7 +237,12 @@ faulthandler_dump_traceback_py(PyObject *self,
return NULL;
if (all_threads) {
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ /* gh-128400: Accessing other thread states while they're running
+ * isn't safe if those threads are running. */
+ _PyEval_StopTheWorld(interp);
errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
+ _PyEval_StartTheWorld(interp);
if (errmsg != NULL) {
PyErr_SetString(PyExc_RuntimeError, errmsg);
return NULL;
_______________________________________________
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]