diff options
author | Neil Schemenauer <nas-github@arctrix.com> | 2025-05-27 18:27:41 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-27 18:27:41 -0700 |
commit | fbbbc10055e0ee0011cf683132be706815480839 (patch) | |
tree | 7c10250ec0564196d4cdfcb79a1d59895639999f /Python/ceval.c | |
parent | 7ca6d79fa32d7203ee8d64f47b6b3539a027fdea (diff) | |
download | cpython-fbbbc10055e0ee0011cf683132be706815480839.tar.gz cpython-fbbbc10055e0ee0011cf683132be706815480839.zip |
gh-127266: avoid data races when updating type slots (gh-133177)
In the free-threaded build, avoid data races caused by updating type
slots or type flags after the type was initially created. For those
(typically rare) cases, use the stop-the-world mechanism. Remove the
use of atomics when reading or writing type flags.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 309c4567f20..4efa4b697fb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -139,6 +139,19 @@ #endif +static void +check_invalid_reentrancy(void) +{ +#if defined(Py_DEBUG) && defined(Py_GIL_DISABLED) + // In the free-threaded build, the interpreter must not be re-entered if + // the world-is-stopped. If so, that's a bug somewhere (quite likely in + // the painfully complex typeobject code). + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(!interp->stoptheworld.world_stopped); +#endif +} + + #ifdef Py_DEBUG static void dump_item(_PyStackRef item) @@ -996,6 +1009,7 @@ PyObject* _Py_HOT_FUNCTION DONT_SLP_VECTORIZE _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) { _Py_EnsureTstateNotNULL(tstate); + check_invalid_reentrancy(); CALL_STAT_INC(pyeval_calls); #if USE_COMPUTED_GOTOS && !Py_TAIL_CALL_INTERP |