diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-08-06-11-56-15.gh-issue-137472.Pr_BLB.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-06-11-56-15.gh-issue-137472.Pr_BLB.rst new file mode 100644 index 00000000000000..acfc4dbdea12de --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-08-06-11-56-15.gh-issue-137472.Pr_BLB.rst @@ -0,0 +1,3 @@ +Fix a crash that can occur in free-threading builds when +``sys._setprofileallthreads`` or ``sys._settraceallthreads`` changes the +profile function underneath a running thread. diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index dbd19d7755c237..0a0d231cb12d0c 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -484,13 +484,19 @@ setup_profile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg, PyObject } } + _PyEval_StopTheWorld(tstate->interp); + int delta = (func != NULL) - (tstate->c_profilefunc != NULL); tstate->c_profilefunc = func; *old_profileobj = tstate->c_profileobj; tstate->c_profileobj = Py_XNewRef(arg); tstate->interp->sys_profiling_threads += delta; assert(tstate->interp->sys_profiling_threads >= 0); - return tstate->interp->sys_profiling_threads; + Py_ssize_t ret = tstate->interp->sys_profiling_threads; + + _PyEval_StartTheWorld(tstate->interp); + + return ret; } int