gh-137400: Fix a crash when disabling profiling across all threads (gh-137471)
Some checks are pending
Tests / (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / Ubuntu SSL tests with AWS-LC (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Sanitizers (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run

The `PyEval_SetProfileAllThreads` function and other related functions
had a race condition on `tstate->c_profilefunc` that could lead to a
crash when disable profiling or tracing on all threads while another
thread is starting to profile or trace a a call.

There are still potential crashes when threads exit concurrently with
profiling or tracing be enabled/disabled across all threads.
This commit is contained in:
Sam Gross 2025-08-11 11:41:44 -04:00 committed by GitHub
parent deb0020e3d
commit 362692852f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 46 additions and 2 deletions

View file

@ -477,13 +477,16 @@ 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 profiling_threads = tstate->interp->sys_profiling_threads;
_PyEval_StartTheWorld(tstate->interp);
return profiling_threads;
}
int
@ -574,13 +577,16 @@ setup_tracing(PyThreadState *tstate, Py_tracefunc func, PyObject *arg, PyObject
}
}
_PyEval_StopTheWorld(tstate->interp);
int delta = (func != NULL) - (tstate->c_tracefunc != NULL);
tstate->c_tracefunc = func;
*old_traceobj = tstate->c_traceobj;
tstate->c_traceobj = Py_XNewRef(arg);
tstate->interp->sys_tracing_threads += delta;
assert(tstate->interp->sys_tracing_threads >= 0);
return tstate->interp->sys_tracing_threads;
Py_ssize_t tracing_threads = tstate->interp->sys_tracing_threads;
_PyEval_StartTheWorld(tstate->interp);
return tracing_threads;
}
int