Skip to content

Commit 950e032

Browse files
Use local events when possible
1 parent 0c4615a commit 950e032

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

Lib/bdb.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ class _MonitoringTracer:
3333
E.INSTRUCTION: 'opcode',
3434
}
3535

36+
GLOBAL_EVENTS = E.PY_START | E.PY_RESUME | E.PY_THROW | E.PY_UNWIND | E.RAISE
37+
LOCAL_EVENTS = E.LINE | E.JUMP | E.PY_RETURN | E.PY_YIELD | E.STOP_ITERATION
38+
3639
def __init__(self):
3740
self._tool_id = sys.monitoring.DEBUGGER_ID
3841
self._name = 'bdbtracer'
3942
self._tracefunc = None
4043
self._disable_current_event = False
4144
self._tracing_thread = None
45+
self._enabled = False
4246

4347
def start_trace(self, tracefunc):
4448
self._tracefunc = tracefunc
@@ -47,7 +51,7 @@ def start_trace(self, tracefunc):
4751
if curr_tool is None:
4852
sys.monitoring.use_tool_id(self._tool_id, self._name)
4953
elif curr_tool == self._name:
50-
sys.monitoring.set_events(self._tool_id, 0)
54+
sys.monitoring.clear_tool_id(self._tool_id)
5155
else:
5256
raise ValueError('Another debugger is using the monitoring tool')
5357
E = sys.monitoring.events
@@ -57,17 +61,18 @@ def start_trace(self, tracefunc):
5761
sys.monitoring.register_callback(self._tool_id, event, callback)
5862
if event != E.INSTRUCTION:
5963
all_events |= event
64+
self.check_trace_func()
6065
self.check_trace_opcodes()
61-
sys.monitoring.set_events(self._tool_id, all_events)
66+
sys.monitoring.set_events(self._tool_id, self.GLOBAL_EVENTS)
67+
self._enabled = True
6268

6369
def stop_trace(self):
70+
self._enabled = False
6471
self._tracing_thread = None
6572
curr_tool = sys.monitoring.get_tool(self._tool_id)
6673
if curr_tool != self._name:
6774
return
68-
for event in self.EVENT_CALLBACK_MAP.keys():
69-
sys.monitoring.register_callback(self._tool_id, event, None)
70-
sys.monitoring.set_events(self._tool_id, 0)
75+
sys.monitoring.clear_tool_id(self._tool_id)
7176
self.check_trace_opcodes()
7277
sys.monitoring.free_tool_id(self._tool_id)
7378

@@ -88,6 +93,8 @@ def wrapper(self, *args):
8893
try:
8994
frame = sys._getframe().f_back
9095
ret = func(self, frame, *args)
96+
if self._enabled and frame.f_trace:
97+
self.check_trace_func()
9198
if self._disable_current_event:
9299
return sys.monitoring.DISABLE
93100
else:
@@ -105,6 +112,8 @@ def call_callback(self, frame, code, *args):
105112
local_tracefunc = self._tracefunc(frame, 'call', None)
106113
if local_tracefunc is not None:
107114
frame.f_trace = local_tracefunc
115+
if self._enabled:
116+
sys.monitoring.set_local_events(self._tool_id, code, self.LOCAL_EVENTS)
108117

109118
@callback_wrapper
110119
def return_callback(self, frame, code, offset, retval):
@@ -163,6 +172,14 @@ def set_trace_opcodes(self, frame, trace_opcodes):
163172
else:
164173
sys.monitoring.set_local_events(self._tool_id, frame.f_code, 0)
165174

175+
def check_trace_func(self, frame=None):
176+
if frame is None:
177+
frame = sys._getframe().f_back
178+
while frame is not None:
179+
if frame.f_trace is not None:
180+
sys.monitoring.set_local_events(self._tool_id, frame.f_code, self.LOCAL_EVENTS)
181+
frame = frame.f_back
182+
166183
def _get_lineno(self, code, offset):
167184
import dis
168185
last_lineno = None

0 commit comments

Comments
 (0)