[3.13] gh-128991: Release the enter frame reference within bdb callba… (#129002)

[3.13] gh-128991: Release the enter frame reference within bdb callback (GH-128992)

* Release the enter frame reference within bdb callback

* 📜🤖 Added by blurb_it.

---------

(cherry picked from commit 61b35f74aa)
This commit is contained in:
Tian Gao 2025-01-18 17:21:23 -05:00 committed by GitHub
parent 03ee311e5a
commit ef9961840b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 32 deletions

View file

@ -3,6 +3,7 @@
import fnmatch
import sys
import os
from contextlib import contextmanager
from inspect import CO_GENERATOR, CO_COROUTINE, CO_ASYNC_GENERATOR
__all__ = ["BdbQuit", "Bdb", "Breakpoint"]
@ -63,6 +64,12 @@ class Bdb:
self.botframe = None
self._set_stopinfo(None, None)
@contextmanager
def set_enterframe(self, frame):
self.enterframe = frame
yield
self.enterframe = None
def trace_dispatch(self, frame, event, arg):
"""Dispatch a trace function for debugged frames based on the event.
@ -88,28 +95,27 @@ class Bdb:
The arg parameter depends on the previous event.
"""
self.enterframe = frame
if self.quitting:
return # None
if event == 'line':
return self.dispatch_line(frame)
if event == 'call':
return self.dispatch_call(frame, arg)
if event == 'return':
return self.dispatch_return(frame, arg)
if event == 'exception':
return self.dispatch_exception(frame, arg)
if event == 'c_call':
with self.set_enterframe(frame):
if self.quitting:
return # None
if event == 'line':
return self.dispatch_line(frame)
if event == 'call':
return self.dispatch_call(frame, arg)
if event == 'return':
return self.dispatch_return(frame, arg)
if event == 'exception':
return self.dispatch_exception(frame, arg)
if event == 'c_call':
return self.trace_dispatch
if event == 'c_exception':
return self.trace_dispatch
if event == 'c_return':
return self.trace_dispatch
if event == 'opcode':
return self.dispatch_opcode(frame, arg)
print('bdb.Bdb.dispatch: unknown debugging event:', repr(event))
return self.trace_dispatch
if event == 'c_exception':
return self.trace_dispatch
if event == 'c_return':
return self.trace_dispatch
if event == 'opcode':
return self.dispatch_opcode(frame, arg)
print('bdb.Bdb.dispatch: unknown debugging event:', repr(event))
return self.trace_dispatch
def dispatch_line(self, frame):
"""Invoke user function and return trace function for line event.
@ -373,16 +379,15 @@ class Bdb:
if frame is None:
frame = sys._getframe().f_back
self.reset()
self.enterframe = frame
while frame:
frame.f_trace = self.trace_dispatch
self.botframe = frame
self.frame_trace_lines_opcodes[frame] = (frame.f_trace_lines, frame.f_trace_opcodes)
# We need f_trace_lines == True for the debugger to work
frame.f_trace_lines = True
frame = frame.f_back
self.set_stepinstr()
self.enterframe = None
with self.set_enterframe(frame):
while frame:
frame.f_trace = self.trace_dispatch
self.botframe = frame
self.frame_trace_lines_opcodes[frame] = (frame.f_trace_lines, frame.f_trace_opcodes)
# We need f_trace_lines == True for the debugger to work
frame.f_trace_lines = True
frame = frame.f_back
self.set_stepinstr()
sys.settrace(self.trace_dispatch)
def set_continue(self):
@ -402,7 +407,6 @@ class Bdb:
for frame, (trace_lines, trace_opcodes) in self.frame_trace_lines_opcodes.items():
frame.f_trace_lines, frame.f_trace_opcodes = trace_lines, trace_opcodes
self.frame_trace_lines_opcodes = {}
self.enterframe = None
def set_quit(self):
"""Set quitting attribute to True.

View file

@ -0,0 +1 @@
Release the enter frame reference within :mod:`bdb` callback