diff options
author | Brett Simmers <swtaarrs@users.noreply.github.com> | 2024-03-04 16:29:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-04 16:29:39 (GMT) |
commit | 0adfa8482d369899e9963206a3307f423309e10c (patch) | |
tree | c1f71c0f65b0f01581d37eafa55c26b769915299 /Python/instrumentation.c | |
parent | 15dc2979bc1b24269177f0e150495abb7f3eb546 (diff) | |
download | cpython-0adfa8482d369899e9963206a3307f423309e10c.zip cpython-0adfa8482d369899e9963206a3307f423309e10c.tar.gz cpython-0adfa8482d369899e9963206a3307f423309e10c.tar.bz2 |
gh-115832: Fix instrumentation version mismatch during interpreter shutdown (#115856)
A previous commit introduced a bug to `interpreter_clear()`: it set
`interp->ceval.instrumentation_version` to 0, without making the corresponding
change to `tstate->eval_breaker` (which holds a thread-local copy of the
version). After this happens, Python code can still run due to object finalizers
during a GC, and the version check in bytecodes.c will see a different result
than the one in instrumentation.c causing an infinite loop.
The fix itself is straightforward: clear `tstate->eval_breaker` when clearing
`interp->ceval.instrumentation_version`.
Diffstat (limited to 'Python/instrumentation.c')
-rw-r--r-- | Python/instrumentation.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/Python/instrumentation.c b/Python/instrumentation.c index 6f1bc2e..018cd66 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -891,8 +891,16 @@ static inline int most_significant_bit(uint8_t bits) { static uint32_t global_version(PyInterpreterState *interp) { - return (uint32_t)_Py_atomic_load_uintptr_relaxed( + uint32_t version = (uint32_t)_Py_atomic_load_uintptr_relaxed( &interp->ceval.instrumentation_version); +#ifdef Py_DEBUG + PyThreadState *tstate = _PyThreadState_GET(); + uint32_t thread_version = + (uint32_t)(_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & + ~_PY_EVAL_EVENTS_MASK); + assert(thread_version == version); +#endif + return version; } /* Atomically set the given version in the given location, without touching |