Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf34e965

Browse files
GH-111744: Support opcode events in bdb (GH-111834)
1 parentf6b5d3b commitf34e965

File tree

4 files changed

+72
-17
lines changed

4 files changed

+72
-17
lines changed

‎Lib/bdb.py‎

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ def __init__(self, skip=None):
3232
self.skip=set(skip)ifskipelseNone
3333
self.breaks= {}
3434
self.fncache= {}
35-
self.frame_trace_lines= {}
35+
self.frame_trace_lines_opcodes= {}
3636
self.frame_returning=None
37+
self.trace_opcodes=False
38+
self.enterframe=None
3739

3840
self._load_breaks()
3941

@@ -85,6 +87,9 @@ def trace_dispatch(self, frame, event, arg):
8587
8688
The arg parameter depends on the previous event.
8789
"""
90+
91+
self.enterframe=frame
92+
8893
ifself.quitting:
8994
return# None
9095
ifevent=='line':
@@ -101,6 +106,8 @@ def trace_dispatch(self, frame, event, arg):
101106
returnself.trace_dispatch
102107
ifevent=='c_return':
103108
returnself.trace_dispatch
109+
ifevent=='opcode':
110+
returnself.dispatch_opcode(frame,arg)
104111
print('bdb.Bdb.dispatch: unknown debugging event:',repr(event))
105112
returnself.trace_dispatch
106113

@@ -187,6 +194,17 @@ def dispatch_exception(self, frame, arg):
187194

188195
returnself.trace_dispatch
189196

197+
defdispatch_opcode(self,frame,arg):
198+
"""Invoke user function and return trace function for opcode event.
199+
If the debugger stops on the current opcode, invoke
200+
self.user_opcode(). Raise BdbQuit if self.quitting is set.
201+
Return self.trace_dispatch to continue tracing in this scope.
202+
"""
203+
ifself.stop_here(frame)orself.break_here(frame):
204+
self.user_opcode(frame)
205+
ifself.quitting:raiseBdbQuit
206+
returnself.trace_dispatch
207+
190208
# Normally derived classes don't override the following
191209
# methods, but they may if they want to redefine the
192210
# definition of stopping and breakpoints.
@@ -273,7 +291,21 @@ def user_exception(self, frame, exc_info):
273291
"""Called when we stop on an exception."""
274292
pass
275293

276-
def_set_stopinfo(self,stopframe,returnframe,stoplineno=0):
294+
defuser_opcode(self,frame):
295+
"""Called when we are about to execute an opcode."""
296+
pass
297+
298+
def_set_trace_opcodes(self,trace_opcodes):
299+
iftrace_opcodes!=self.trace_opcodes:
300+
self.trace_opcodes=trace_opcodes
301+
frame=self.enterframe
302+
whileframeisnotNone:
303+
frame.f_trace_opcodes=trace_opcodes
304+
ifframeisself.botframe:
305+
break
306+
frame=frame.f_back
307+
308+
def_set_stopinfo(self,stopframe,returnframe,stoplineno=0,opcode=False):
277309
"""Set the attributes for stopping.
278310
279311
If stoplineno is greater than or equal to 0, then stop at line
@@ -286,6 +318,17 @@ def _set_stopinfo(self, stopframe, returnframe, stoplineno=0):
286318
# stoplineno >= 0 means: stop at line >= the stoplineno
287319
# stoplineno -1 means: don't stop at all
288320
self.stoplineno=stoplineno
321+
self._set_trace_opcodes(opcode)
322+
323+
def_set_caller_tracefunc(self):
324+
# Issue #13183: pdb skips frames after hitting a breakpoint and running
325+
# step commands.
326+
# Restore the trace function in the caller (that may not have been set
327+
# for performance reasons) when returning from the current frame.
328+
ifself.frame_returning:
329+
caller_frame=self.frame_returning.f_back
330+
ifcaller_frameandnotcaller_frame.f_trace:
331+
caller_frame.f_trace=self.trace_dispatch
289332

290333
# Derived classes and clients can call the following methods
291334
# to affect the stepping state.
@@ -300,16 +343,14 @@ def set_until(self, frame, lineno=None):
300343

301344
defset_step(self):
302345
"""Stop after one line of code."""
303-
# Issue #13183: pdb skips frames after hitting a breakpoint and running
304-
# step commands.
305-
# Restore the trace function in the caller (that may not have been set
306-
# for performance reasons) when returning from the current frame.
307-
ifself.frame_returning:
308-
caller_frame=self.frame_returning.f_back
309-
ifcaller_frameandnotcaller_frame.f_trace:
310-
caller_frame.f_trace=self.trace_dispatch
346+
self._set_caller_tracefunc()
311347
self._set_stopinfo(None,None)
312348

349+
defset_stepinstr(self):
350+
"""Stop before the next instruction."""
351+
self._set_caller_tracefunc()
352+
self._set_stopinfo(None,None,opcode=True)
353+
313354
defset_next(self,frame):
314355
"""Stop on the next line in or below the given frame."""
315356
self._set_stopinfo(frame,None)
@@ -329,11 +370,12 @@ def set_trace(self, frame=None):
329370
ifframeisNone:
330371
frame=sys._getframe().f_back
331372
self.reset()
373+
self.enterframe=frame
332374
whileframe:
333375
frame.f_trace=self.trace_dispatch
334376
self.botframe=frame
335-
# We need f_trace_liens == True for the debugger to work
336-
self.frame_trace_lines[frame]=frame.f_trace_lines
377+
self.frame_trace_lines_opcodes[frame]= (frame.f_trace_lines,frame.f_trace_opcodes)
378+
# We needf_trace_lines == True for the debugger to work
337379
frame.f_trace_lines=True
338380
frame=frame.f_back
339381
self.set_step()
@@ -353,9 +395,9 @@ def set_continue(self):
353395
whileframeandframeisnotself.botframe:
354396
delframe.f_trace
355397
frame=frame.f_back
356-
forframe,prev_trace_linesinself.frame_trace_lines.items():
357-
frame.f_trace_lines=prev_trace_lines
358-
self.frame_trace_lines= {}
398+
forframe,(trace_lines,trace_opcodes)inself.frame_trace_lines_opcodes.items():
399+
frame.f_trace_lines,frame.f_trace_opcodes=trace_lines,trace_opcodes
400+
self.frame_trace_lines_opcodes= {}
359401

360402
defset_quit(self):
361403
"""Set quitting attribute to True.

‎Lib/test/test_bdb.py‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ def user_exception(self, frame, exc_info):
228228
self.process_event('exception',frame)
229229
self.next_set_method()
230230

231+
defuser_opcode(self,frame):
232+
self.process_event('opcode',frame)
233+
self.next_set_method()
234+
231235
defdo_clear(self,arg):
232236
# The temporary breakpoints are deleted in user_line().
233237
bp_list= [self.currentbp]
@@ -366,7 +370,7 @@ def next_set_method(self):
366370
set_method=getattr(self,'set_'+set_type)
367371

368372
# The following set methods give back control to the tracer.
369-
ifset_typein ('step','continue','quit'):
373+
ifset_typein ('step','stepinstr','continue','quit'):
370374
set_method()
371375
return
372376
elifset_typein ('next','return'):
@@ -610,6 +614,15 @@ def test_step_next_on_last_statement(self):
610614
withTracerRun(self)astracer:
611615
tracer.runcall(tfunc_main)
612616

617+
deftest_stepinstr(self):
618+
self.expect_set= [
619+
('line',2,'tfunc_main'), ('stepinstr', ),
620+
('opcode',2,'tfunc_main'), ('next', ),
621+
('line',3,'tfunc_main'), ('quit', ),
622+
]
623+
withTracerRun(self)astracer:
624+
tracer.runcall(tfunc_main)
625+
613626
deftest_next(self):
614627
self.expect_set= [
615628
('line',2,'tfunc_main'), ('step', ),

‎Lib/test/test_pdb.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2456,7 +2456,6 @@ def test_pdb_issue_gh_108976():
24562456
... 'continue'
24572457
... ]):
24582458
... test_function()
2459-
bdb.Bdb.dispatch: unknown debugging event: 'opcode'
24602459
> <doctest test.test_pdb.test_pdb_issue_gh_108976[0]>(5)test_function()
24612460
-> a = 1
24622461
(Pdb) continue
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support opcode events in:mod:`bdb`

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp