mirror of
https://github.com/python/cpython.git
synced 2025-09-02 15:07:53 +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
30
Lib/test/_test_monitoring_shutdown.py
Normal file
30
Lib/test/_test_monitoring_shutdown.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# gh-115832: An object destructor running during the final GC of interpreter
|
||||
# shutdown triggered an infinite loop in the instrumentation code.
|
||||
|
||||
import sys
|
||||
|
||||
class CallableCycle:
|
||||
def __init__(self):
|
||||
self._cycle = self
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
def __call__(self, code, instruction_offset):
|
||||
pass
|
||||
|
||||
def tracefunc(frame, event, arg):
|
||||
pass
|
||||
|
||||
def main():
|
||||
tool_id = sys.monitoring.PROFILER_ID
|
||||
event_id = sys.monitoring.events.PY_START
|
||||
|
||||
sys.monitoring.use_tool_id(tool_id, "test profiler")
|
||||
sys.monitoring.set_events(tool_id, event_id)
|
||||
sys.monitoring.register_callback(tool_id, event_id, CallableCycle())
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
Loading…
Add table
Add a link
Reference in a new issue