Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(4)

Side by Side Diff: Lib/bdb.py

Issue 13183: pdb skips frames after hitting a breakpoint and running step
Patch Set: Created 8 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Lib/test/test_pdb.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 """Debugger basics""" 1 """Debugger basics"""
2 2
3 import fnmatch 3 import fnmatch
4 import sys 4 import sys
5 import os 5 import os
6 6
7 __all__ = ["BdbQuit", "Bdb", "Breakpoint"] 7 __all__ = ["BdbQuit", "Bdb", "Breakpoint"]
8 8
9 class BdbQuit(Exception): 9 class BdbQuit(Exception):
10 """Exception to give up completely.""" 10 """Exception to give up completely."""
11 11
12 12
13 class Bdb: 13 class Bdb:
14 """Generic Python debugger base class. 14 """Generic Python debugger base class.
15 15
16 This class takes care of details of the trace facility; 16 This class takes care of details of the trace facility;
17 a derived class should implement user interaction. 17 a derived class should implement user interaction.
18 The standard debugger class (pdb.Pdb) is an example. 18 The standard debugger class (pdb.Pdb) is an example.
19 """ 19 """
20 20
21 def __init__(self, skip=None): 21 def __init__(self, skip=None):
22 self.skip = set(skip) if skip else None 22 self.skip = set(skip) if skip else None
23 self.breaks = {} 23 self.breaks = {}
24 self.fncache = {} 24 self.fncache = {}
25 self.frame_returning = None
25 26
26 def canonic(self, filename): 27 def canonic(self, filename):
27 if filename == "<" + filename[1:-1] + ">": 28 if filename == "<" + filename[1:-1] + ">":
28 return filename 29 return filename
29 canonic = self.fncache.get(filename) 30 canonic = self.fncache.get(filename)
30 if not canonic: 31 if not canonic:
31 canonic = os.path.abspath(filename) 32 canonic = os.path.abspath(filename)
32 canonic = os.path.normcase(canonic) 33 canonic = os.path.normcase(canonic)
33 self.fncache[filename] = canonic 34 self.fncache[filename] = canonic
34 return canonic 35 return canonic
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 return self.trace_dispatch 74 return self.trace_dispatch
74 if not (self.stop_here(frame) or self.break_anywhere(frame)): 75 if not (self.stop_here(frame) or self.break_anywhere(frame)):
75 # No need to trace this function 76 # No need to trace this function
76 return # None 77 return # None
77 self.user_call(frame, arg) 78 self.user_call(frame, arg)
78 if self.quitting: raise BdbQuit 79 if self.quitting: raise BdbQuit
79 return self.trace_dispatch 80 return self.trace_dispatch
80 81
81 def dispatch_return(self, frame, arg): 82 def dispatch_return(self, frame, arg):
82 if self.stop_here(frame) or frame == self.returnframe: 83 if self.stop_here(frame) or frame == self.returnframe:
84 self.frame_returning = frame
83 self.user_return(frame, arg) 85 self.user_return(frame, arg)
86 self.frame_returning = None
84 if self.quitting: raise BdbQuit 87 if self.quitting: raise BdbQuit
85 return self.trace_dispatch 88 return self.trace_dispatch
86 89
87 def dispatch_exception(self, frame, arg): 90 def dispatch_exception(self, frame, arg):
88 if self.stop_here(frame): 91 if self.stop_here(frame):
89 self.user_exception(frame, arg) 92 self.user_exception(frame, arg)
90 if self.quitting: raise BdbQuit 93 if self.quitting: raise BdbQuit
91 return self.trace_dispatch 94 return self.trace_dispatch
92 95
93 # Normally derived classes don't override the following 96 # Normally derived classes don't override the following
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 def set_until(self, frame, lineno=None): 182 def set_until(self, frame, lineno=None):
180 """Stop when the line with the line no greater than the current one is 183 """Stop when the line with the line no greater than the current one is
181 reached or when returning from current frame""" 184 reached or when returning from current frame"""
182 # the name "until" is borrowed from gdb 185 # the name "until" is borrowed from gdb
183 if lineno is None: 186 if lineno is None:
184 lineno = frame.f_lineno + 1 187 lineno = frame.f_lineno + 1
185 self._set_stopinfo(frame, frame, lineno) 188 self._set_stopinfo(frame, frame, lineno)
186 189
187 def set_step(self): 190 def set_step(self):
188 """Stop after one line of code.""" 191 """Stop after one line of code."""
192 # Issue #13183: pdb skips frames after hitting a breakpoint and running
193 # step commands.
194 # Restore the trace function in the caller (that may not have been set
195 # for performance reasons) when returning from the current frame.
196 if self.frame_returning:
197 caller_frame = self.frame_returning.f_back
198 if caller_frame and not caller_frame.f_trace:
199 caller_frame.f_trace = self.trace_dispatch
189 self._set_stopinfo(None, None) 200 self._set_stopinfo(None, None)
190 201
191 def set_next(self, frame): 202 def set_next(self, frame):
192 """Stop on the next line in or below the given frame.""" 203 """Stop on the next line in or below the given frame."""
193 self._set_stopinfo(frame, None) 204 self._set_stopinfo(frame, None)
194 205
195 def set_return(self, frame): 206 def set_return(self, frame):
196 """Stop when returning from the given frame.""" 207 """Stop when returning from the given frame."""
197 self._set_stopinfo(frame.f_back, frame) 208 self._set_stopinfo(frame.f_back, frame)
198 209
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 x = bar(n*10) 636 x = bar(n*10)
626 print('bar returned', x) 637 print('bar returned', x)
627 638
628 def bar(a): 639 def bar(a):
629 print('bar(', a, ')') 640 print('bar(', a, ')')
630 return a/2 641 return a/2
631 642
632 def test(): 643 def test():
633 t = Tdb() 644 t = Tdb()
634 t.run('import bdb; bdb.foo(10)') 645 t.run('import bdb; bdb.foo(10)')
OLDNEW
« no previous file with comments | « no previous file | Lib/test/test_pdb.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+