mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
[3.13] gh-128400: Stop-the-world when manually calling faulthandler
(GH-128422) (GH-128423)
(cherry picked from commit c9356feef2
)
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
parent
fa6c48e4b3
commit
ebadfd1039
3 changed files with 36 additions and 1 deletions
|
@ -7,7 +7,7 @@ import signal
|
|||
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 @@ class FaultHandlerTests(unittest.TestCase):
|
|||
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()
|
||||
|
|
|
@ -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.
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue