mirror of
https://github.com/python/cpython.git
synced 2025-07-12 22:05:16 +00:00
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`.
This commit is contained in:
parent
15dc2979bc
commit
0adfa8482d
4 changed files with 53 additions and 2 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue