mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	 0adfa8482d
			
		
	
	
		0adfa8482d
		
			
		
	
	
	
	
		
			
			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`.
		
			
				
	
	
		
			30 lines
		
	
	
	
		
			727 B
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			30 lines
		
	
	
	
		
			727 B
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/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())
 |