blob: d74415bf14771fd29777e7ece80654777d4552a6 [file] [log] [blame]
Guido van Rossum4acc25b2000-02-02 15:10:15 +00001"""Debugger basics"""
Guido van Rossumbabe2bf1992-01-22 22:21:31 +00002
3import sys
Barry Warsaw148ffbc1999-09-09 23:24:33 +00004import os
Guido van Rossum4808dcb1996-10-15 14:40:21 +00005import types
Guido van Rossumbabe2bf1992-01-22 22:21:31 +00006
Skip Montanaroe99d5ea2001-01-20 19:54:20 +00007__all__ = ["BdbQuit","Bdb","Breakpoint"]
8
Neal Norwitz93cf79f2002-03-31 14:06:41 +00009class BdbQuit(Exception):
10 """Exception to give up completely"""
Guido van Rossumbabe2bf1992-01-22 22:21:31 +000011
12
Guido van Rossum6ea27cc1999-01-25 20:51:34 +000013class Bdb:
Tim Peters11cf6052001-01-14 21:54:20 +000014
Guido van Rossum4acc25b2000-02-02 15:10:15 +000015 """Generic Python debugger base class.
Guido van Rossum6ea27cc1999-01-25 20:51:34 +000016
Guido van Rossum4acc25b2000-02-02 15:10:15 +000017 This class takes care of details of the trace facility;
18 a derived class should implement user interaction.
19 The standard debugger class (pdb.Pdb) is an example.
20 """
Guido van Rossum6ea27cc1999-01-25 20:51:34 +000021
Guido van Rossum4acc25b2000-02-02 15:10:15 +000022 def __init__(self):
23 self.breaks = {}
24 self.fncache = {}
Barry Warsaw148ffbc1999-09-09 23:24:33 +000025
Guido van Rossum4acc25b2000-02-02 15:10:15 +000026 def canonic(self, filename):
Guido van Rossum42f53322001-11-29 02:50:15 +000027 if filename == "<" + filename[1:-1] + ">":
28 return filename
Guido van Rossum4acc25b2000-02-02 15:10:15 +000029 canonic = self.fncache.get(filename)
30 if not canonic:
31 canonic = os.path.abspath(filename)
Guido van Rossumbdba3202002-02-25 23:23:24 +000032 canonic = os.path.normcase(canonic)
Guido van Rossum4acc25b2000-02-02 15:10:15 +000033 self.fncache[filename] = canonic
34 return canonic
Tim Peters11cf6052001-01-14 21:54:20 +000035
Guido van Rossum4acc25b2000-02-02 15:10:15 +000036 def reset(self):
37 import linecache
38 linecache.checkcache()
39 self.botframe = None
Benjamin Peterson98353942008-05-11 14:13:25 +000040 self._set_stopinfo(None, None)
Tim Peters11cf6052001-01-14 21:54:20 +000041
Guido van Rossum4acc25b2000-02-02 15:10:15 +000042 def trace_dispatch(self, frame, event, arg):
43 if self.quitting:
44 return # None
45 if event == 'line':
46 return self.dispatch_line(frame)
47 if event == 'call':
48 return self.dispatch_call(frame, arg)
49 if event == 'return':
50 return self.dispatch_return(frame, arg)
51 if event == 'exception':
52 return self.dispatch_exception(frame, arg)
Nicholas Bastinc69ebe82004-03-24 21:57:10 +000053 if event == 'c_call':
54 return self.trace_dispatch
55 if event == 'c_exception':
56 return self.trace_dispatch
57 if event == 'c_return':
58 return self.trace_dispatch
Walter Dörwald70a6b492004-02-12 17:35:32 +000059 print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event)
Guido van Rossum4acc25b2000-02-02 15:10:15 +000060 return self.trace_dispatch
Tim Peters11cf6052001-01-14 21:54:20 +000061
Guido van Rossum4acc25b2000-02-02 15:10:15 +000062 def dispatch_line(self, frame):
63 if self.stop_here(frame) or self.break_here(frame):
64 self.user_line(frame)
65 if self.quitting: raise BdbQuit
66 return self.trace_dispatch
Tim Peters11cf6052001-01-14 21:54:20 +000067
Guido van Rossum4acc25b2000-02-02 15:10:15 +000068 def dispatch_call(self, frame, arg):
69 # XXX 'arg' is no longer used
70 if self.botframe is None:
71 # First call of dispatch since reset()
Christian Tismer313a7512002-05-28 08:04:00 +000072 self.botframe = frame.f_back # (CT) Note that this may also be None!
Guido van Rossum4acc25b2000-02-02 15:10:15 +000073 return self.trace_dispatch
74 if not (self.stop_here(frame) or self.break_anywhere(frame)):
75 # No need to trace this function
76 return # None
77 self.user_call(frame, arg)
78 if self.quitting: raise BdbQuit
79 return self.trace_dispatch
Tim Peters11cf6052001-01-14 21:54:20 +000080
Guido van Rossum4acc25b2000-02-02 15:10:15 +000081 def dispatch_return(self, frame, arg):
82 if self.stop_here(frame) or frame == self.returnframe:
83 self.user_return(frame, arg)
84 if self.quitting: raise BdbQuit
Just van Rossumae1f65f2001-06-25 18:01:24 +000085 return self.trace_dispatch
Tim Peters11cf6052001-01-14 21:54:20 +000086
Guido van Rossum4acc25b2000-02-02 15:10:15 +000087 def dispatch_exception(self, frame, arg):
88 if self.stop_here(frame):
89 self.user_exception(frame, arg)
90 if self.quitting: raise BdbQuit
91 return self.trace_dispatch
Tim Peters11cf6052001-01-14 21:54:20 +000092
Guido van Rossum4acc25b2000-02-02 15:10:15 +000093 # Normally derived classes don't override the following
94 # methods, but they may if they want to redefine the
95 # definition of stopping and breakpoints.
Tim Peters11cf6052001-01-14 21:54:20 +000096
Guido van Rossum4acc25b2000-02-02 15:10:15 +000097 def stop_here(self, frame):
Neal Norwitz72a2b4d2002-05-29 00:54:38 +000098 # (CT) stopframe may now also be None, see dispatch_call.
99 # (CT) the former test for None is therefore removed from here.
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000100 if frame is self.stopframe:
Benjamin Peterson98353942008-05-11 14:13:25 +0000101 return frame.f_lineno >= self.stoplineno
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000102 while frame is not None and frame is not self.stopframe:
103 if frame is self.botframe:
Tim Petersbc0e9102002-04-04 22:55:58 +0000104 return True
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000105 frame = frame.f_back
Tim Petersbc0e9102002-04-04 22:55:58 +0000106 return False
Guido van Rossumd93643f1998-09-11 22:38:35 +0000107
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000108 def break_here(self, frame):
109 filename = self.canonic(frame.f_code.co_filename)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000110 if not filename in self.breaks:
Tim Petersbc0e9102002-04-04 22:55:58 +0000111 return False
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000112 lineno = frame.f_lineno
113 if not lineno in self.breaks[filename]:
Johannes Gijsbers4a9faa12004-08-30 13:29:44 +0000114 # The line itself has no breakpoint, but maybe the line is the
115 # first line of a function with breakpoint set by function name.
116 lineno = frame.f_code.co_firstlineno
117 if not lineno in self.breaks[filename]:
118 return False
119
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000120 # flag says ok to delete temp. bp
121 (bp, flag) = effective(filename, lineno, frame)
122 if bp:
123 self.currentbp = bp.number
124 if (flag and bp.temporary):
125 self.do_clear(str(bp.number))
Tim Petersbc0e9102002-04-04 22:55:58 +0000126 return True
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000127 else:
Tim Petersbc0e9102002-04-04 22:55:58 +0000128 return False
Tim Peters11cf6052001-01-14 21:54:20 +0000129
Guido van Rossum9cec8fb2001-04-08 15:05:16 +0000130 def do_clear(self, arg):
131 raise NotImplementedError, "subclass of bdb must implement do_clear()"
132
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000133 def break_anywhere(self, frame):
Brett Cannonc6a30ec2008-08-01 01:36:47 +0000134 return self.canonic(frame.f_code.co_filename) in self.breaks
Tim Peters11cf6052001-01-14 21:54:20 +0000135
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000136 # Derived classes should override the user_* methods
137 # to gain control.
Tim Peters11cf6052001-01-14 21:54:20 +0000138
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000139 def user_call(self, frame, argument_list):
140 """This method is called when there is the remote possibility
141 that we ever need to stop in this function."""
142 pass
Tim Peters11cf6052001-01-14 21:54:20 +0000143
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000144 def user_line(self, frame):
145 """This method is called when we stop or break at this line."""
146 pass
Tim Peters11cf6052001-01-14 21:54:20 +0000147
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000148 def user_return(self, frame, return_value):
149 """This method is called when a return trap is set here."""
150 pass
Tim Peters11cf6052001-01-14 21:54:20 +0000151
Brett Cannonc6a30ec2008-08-01 01:36:47 +0000152 def user_exception(self, frame, exc_info):
153 exc_type, exc_value, exc_traceback = exc_info
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000154 """This method is called if an exception occurs,
155 but only if we are to stop at or just below this level."""
156 pass
Tim Peters11cf6052001-01-14 21:54:20 +0000157
Benjamin Peterson98353942008-05-11 14:13:25 +0000158 def _set_stopinfo(self, stopframe, returnframe, stoplineno=-1):
159 self.stopframe = stopframe
160 self.returnframe = returnframe
161 self.quitting = 0
162 self.stoplineno = stoplineno
163
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000164 # Derived classes and clients can call the following methods
165 # to affect the stepping state.
Tim Peters11cf6052001-01-14 21:54:20 +0000166
Benjamin Peterson98353942008-05-11 14:13:25 +0000167 def set_until(self, frame): #the name "until" is borrowed from gdb
168 """Stop when the line with the line no greater than the current one is
169 reached or when returning from current frame"""
170 self._set_stopinfo(frame, frame, frame.f_lineno+1)
171
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000172 def set_step(self):
173 """Stop after one line of code."""
Benjamin Peterson98353942008-05-11 14:13:25 +0000174 self._set_stopinfo(None,None)
Tim Peters11cf6052001-01-14 21:54:20 +0000175
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000176 def set_next(self, frame):
177 """Stop on the next line in or below the given frame."""
Benjamin Peterson98353942008-05-11 14:13:25 +0000178 self._set_stopinfo(frame, None)
Tim Peters11cf6052001-01-14 21:54:20 +0000179
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000180 def set_return(self, frame):
181 """Stop when returning from the given frame."""
Benjamin Peterson98353942008-05-11 14:13:25 +0000182 self._set_stopinfo(frame.f_back, frame)
Tim Peters11cf6052001-01-14 21:54:20 +0000183
Johannes Gijsbers84a6c202004-11-07 11:35:30 +0000184 def set_trace(self, frame=None):
185 """Start debugging from `frame`.
186
187 If frame is not specified, debugging starts from caller's frame.
188 """
189 if frame is None:
190 frame = sys._getframe().f_back
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000191 self.reset()
192 while frame:
193 frame.f_trace = self.trace_dispatch
194 self.botframe = frame
195 frame = frame.f_back
196 self.set_step()
197 sys.settrace(self.trace_dispatch)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000199 def set_continue(self):
200 # Don't stop except at breakpoints or when finished
Benjamin Peterson98353942008-05-11 14:13:25 +0000201 self._set_stopinfo(self.botframe, None)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000202 if not self.breaks:
203 # no breakpoints; run without debugger overhead
204 sys.settrace(None)
Christian Tismer313a7512002-05-28 08:04:00 +0000205 frame = sys._getframe().f_back
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000206 while frame and frame is not self.botframe:
207 del frame.f_trace
208 frame = frame.f_back
Tim Peters11cf6052001-01-14 21:54:20 +0000209
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000210 def set_quit(self):
211 self.stopframe = self.botframe
212 self.returnframe = None
213 self.quitting = 1
214 sys.settrace(None)
Tim Peters11cf6052001-01-14 21:54:20 +0000215
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000216 # Derived classes and clients can call the following methods
217 # to manipulate breakpoints. These methods return an
218 # error message is something went wrong, None if all is well.
219 # Set_break prints out the breakpoint line and file:lineno.
220 # Call self.get_*break*() to see the breakpoints or better
221 # for bp in Breakpoint.bpbynumber: if bp: bp.bpprint().
Tim Peters11cf6052001-01-14 21:54:20 +0000222
Johannes Gijsbers4a9faa12004-08-30 13:29:44 +0000223 def set_break(self, filename, lineno, temporary=0, cond = None,
224 funcname=None):
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000225 filename = self.canonic(filename)
226 import linecache # Import as late as possible
227 line = linecache.getline(filename, lineno)
228 if not line:
229 return 'Line %s:%d does not exist' % (filename,
230 lineno)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000231 if not filename in self.breaks:
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000232 self.breaks[filename] = []
233 list = self.breaks[filename]
234 if not lineno in list:
235 list.append(lineno)
Johannes Gijsbers4a9faa12004-08-30 13:29:44 +0000236 bp = Breakpoint(filename, lineno, temporary, cond, funcname)
Guido van Rossumd93643f1998-09-11 22:38:35 +0000237
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000238 def clear_break(self, filename, lineno):
239 filename = self.canonic(filename)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000240 if not filename in self.breaks:
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000241 return 'There are no breakpoints in %s' % filename
242 if lineno not in self.breaks[filename]:
243 return 'There is no breakpoint at %s:%d' % (filename,
244 lineno)
245 # If there's only one bp in the list for that file,line
246 # pair, then remove the breaks entry
247 for bp in Breakpoint.bplist[filename, lineno][:]:
248 bp.deleteMe()
249 if not Breakpoint.bplist.has_key((filename, lineno)):
250 self.breaks[filename].remove(lineno)
251 if not self.breaks[filename]:
252 del self.breaks[filename]
Tim Peters11cf6052001-01-14 21:54:20 +0000253
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000254 def clear_bpbynumber(self, arg):
255 try:
256 number = int(arg)
257 except:
258 return 'Non-numeric breakpoint number (%s)' % arg
259 try:
260 bp = Breakpoint.bpbynumber[number]
261 except IndexError:
262 return 'Breakpoint number (%d) out of range' % number
263 if not bp:
264 return 'Breakpoint (%d) already deleted' % number
265 self.clear_break(bp.file, bp.line)
Guido van Rossum6ea27cc1999-01-25 20:51:34 +0000266
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000267 def clear_all_file_breaks(self, filename):
268 filename = self.canonic(filename)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000269 if not filename in self.breaks:
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000270 return 'There are no breakpoints in %s' % filename
271 for line in self.breaks[filename]:
272 blist = Breakpoint.bplist[filename, line]
273 for bp in blist:
274 bp.deleteMe()
275 del self.breaks[filename]
Tim Peters11cf6052001-01-14 21:54:20 +0000276
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000277 def clear_all_breaks(self):
278 if not self.breaks:
279 return 'There are no breakpoints'
280 for bp in Breakpoint.bpbynumber:
281 if bp:
282 bp.deleteMe()
283 self.breaks = {}
Tim Peters11cf6052001-01-14 21:54:20 +0000284
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000285 def get_break(self, filename, lineno):
286 filename = self.canonic(filename)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000287 return filename in self.breaks and \
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000288 lineno in self.breaks[filename]
Tim Peters11cf6052001-01-14 21:54:20 +0000289
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000290 def get_breaks(self, filename, lineno):
291 filename = self.canonic(filename)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000292 return filename in self.breaks and \
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000293 lineno in self.breaks[filename] and \
294 Breakpoint.bplist[filename, lineno] or []
Tim Peters11cf6052001-01-14 21:54:20 +0000295
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000296 def get_file_breaks(self, filename):
297 filename = self.canonic(filename)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000298 if filename in self.breaks:
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000299 return self.breaks[filename]
300 else:
301 return []
Tim Peters11cf6052001-01-14 21:54:20 +0000302
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000303 def get_all_breaks(self):
304 return self.breaks
Tim Peters11cf6052001-01-14 21:54:20 +0000305
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000306 # Derived classes and clients can call the following method
307 # to get a data structure representing a stack trace.
Tim Peters11cf6052001-01-14 21:54:20 +0000308
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000309 def get_stack(self, f, t):
310 stack = []
311 if t and t.tb_frame is f:
312 t = t.tb_next
313 while f is not None:
314 stack.append((f, f.f_lineno))
315 if f is self.botframe:
316 break
317 f = f.f_back
318 stack.reverse()
319 i = max(0, len(stack) - 1)
320 while t is not None:
321 stack.append((t.tb_frame, t.tb_lineno))
322 t = t.tb_next
323 return stack, i
Tim Peters11cf6052001-01-14 21:54:20 +0000324
325 #
326
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000327 def format_stack_entry(self, frame_lineno, lprefix=': '):
Brett Cannon2ee0e8e2008-05-23 05:03:59 +0000328 import linecache, repr
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000329 frame, lineno = frame_lineno
330 filename = self.canonic(frame.f_code.co_filename)
Walter Dörwald70a6b492004-02-12 17:35:32 +0000331 s = '%s(%r)' % (filename, lineno)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000332 if frame.f_code.co_name:
333 s = s + frame.f_code.co_name
334 else:
335 s = s + "<lambda>"
Raymond Hettinger54f02222002-06-01 14:18:47 +0000336 if '__args__' in frame.f_locals:
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000337 args = frame.f_locals['__args__']
338 else:
339 args = None
340 if args:
Brett Cannon2ee0e8e2008-05-23 05:03:59 +0000341 s = s + repr.repr(args)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000342 else:
343 s = s + '()'
Raymond Hettinger54f02222002-06-01 14:18:47 +0000344 if '__return__' in frame.f_locals:
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000345 rv = frame.f_locals['__return__']
346 s = s + '->'
Brett Cannon2ee0e8e2008-05-23 05:03:59 +0000347 s = s + repr.repr(rv)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000348 line = linecache.getline(filename, lineno)
Eric S. Raymondb49f4a42001-02-09 05:07:04 +0000349 if line: s = s + lprefix + line.strip()
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000350 return s
Tim Peters11cf6052001-01-14 21:54:20 +0000351
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000352 # The following two methods can be called by clients to use
353 # a debugger to debug a statement, given as a string.
Tim Peters11cf6052001-01-14 21:54:20 +0000354
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000355 def run(self, cmd, globals=None, locals=None):
356 if globals is None:
357 import __main__
358 globals = __main__.__dict__
359 if locals is None:
360 locals = globals
361 self.reset()
362 sys.settrace(self.trace_dispatch)
363 if not isinstance(cmd, types.CodeType):
364 cmd = cmd+'\n'
365 try:
Benjamin Peterson41cf50d2008-03-28 20:56:00 +0000366 exec cmd in globals, locals
367 except BdbQuit:
368 pass
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000369 finally:
370 self.quitting = 1
371 sys.settrace(None)
Tim Peters11cf6052001-01-14 21:54:20 +0000372
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000373 def runeval(self, expr, globals=None, locals=None):
374 if globals is None:
375 import __main__
376 globals = __main__.__dict__
377 if locals is None:
378 locals = globals
379 self.reset()
380 sys.settrace(self.trace_dispatch)
381 if not isinstance(expr, types.CodeType):
382 expr = expr+'\n'
383 try:
Benjamin Peterson41cf50d2008-03-28 20:56:00 +0000384 return eval(expr, globals, locals)
385 except BdbQuit:
386 pass
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000387 finally:
388 self.quitting = 1
389 sys.settrace(None)
Guido van Rossum5e38b6f1995-02-27 13:13:40 +0000390
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000391 def runctx(self, cmd, globals, locals):
392 # B/W compatibility
393 self.run(cmd, globals, locals)
Guido van Rossum4e160981992-09-02 20:43:20 +0000394
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000395 # This method is more useful to debug a single function call.
Guido van Rossum4e160981992-09-02 20:43:20 +0000396
Raymond Hettinger2ef7e6c2004-10-24 00:32:24 +0000397 def runcall(self, func, *args, **kwds):
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000398 self.reset()
399 sys.settrace(self.trace_dispatch)
400 res = None
401 try:
Benjamin Peterson41cf50d2008-03-28 20:56:00 +0000402 res = func(*args, **kwds)
403 except BdbQuit:
404 pass
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000405 finally:
406 self.quitting = 1
407 sys.settrace(None)
408 return res
Guido van Rossumbabe2bf1992-01-22 22:21:31 +0000409
Guido van Rossumbabe2bf1992-01-22 22:21:31 +0000410
Guido van Rossumb6775db1994-08-01 11:34:53 +0000411def set_trace():
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000412 Bdb().set_trace()
Guido van Rossumb6775db1994-08-01 11:34:53 +0000413
Guido van Rossumd93643f1998-09-11 22:38:35 +0000414
415class Breakpoint:
416
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000417 """Breakpoint class
Guido van Rossumd93643f1998-09-11 22:38:35 +0000418
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000419 Implements temporary breakpoints, ignore counts, disabling and
420 (re)-enabling, and conditionals.
Guido van Rossumd93643f1998-09-11 22:38:35 +0000421
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000422 Breakpoints are indexed by number through bpbynumber and by
423 the file,line tuple using bplist. The former points to a
424 single instance of class Breakpoint. The latter points to a
425 list of such instances since there may be more than one
426 breakpoint per line.
Guido van Rossumd93643f1998-09-11 22:38:35 +0000427
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000428 """
Guido van Rossumd93643f1998-09-11 22:38:35 +0000429
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000430 # XXX Keeping state in the class is a mistake -- this means
431 # you cannot have more than one active Bdb instance.
Guido van Rossumd93643f1998-09-11 22:38:35 +0000432
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000433 next = 1 # Next bp to be assigned
434 bplist = {} # indexed by (file, lineno) tuple
435 bpbynumber = [None] # Each entry is None or an instance of Bpt
436 # index 0 is unused, except for marking an
437 # effective break .... see effective()
Guido van Rossumd93643f1998-09-11 22:38:35 +0000438
Johannes Gijsbers4a9faa12004-08-30 13:29:44 +0000439 def __init__(self, file, line, temporary=0, cond=None, funcname=None):
440 self.funcname = funcname
441 # Needed if funcname is not None.
442 self.func_first_executable_line = None
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000443 self.file = file # This better be in canonical form!
444 self.line = line
445 self.temporary = temporary
446 self.cond = cond
447 self.enabled = 1
448 self.ignore = 0
449 self.hits = 0
450 self.number = Breakpoint.next
451 Breakpoint.next = Breakpoint.next + 1
452 # Build the two lists
453 self.bpbynumber.append(self)
454 if self.bplist.has_key((file, line)):
455 self.bplist[file, line].append(self)
456 else:
457 self.bplist[file, line] = [self]
Guido van Rossumd93643f1998-09-11 22:38:35 +0000458
Tim Peters11cf6052001-01-14 21:54:20 +0000459
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000460 def deleteMe(self):
461 index = (self.file, self.line)
462 self.bpbynumber[self.number] = None # No longer in list
463 self.bplist[index].remove(self)
464 if not self.bplist[index]:
465 # No more bp for this f:l combo
466 del self.bplist[index]
Guido van Rossumd93643f1998-09-11 22:38:35 +0000467
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000468 def enable(self):
469 self.enabled = 1
Guido van Rossumd93643f1998-09-11 22:38:35 +0000470
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000471 def disable(self):
472 self.enabled = 0
Guido van Rossumd93643f1998-09-11 22:38:35 +0000473
Georg Brandl19564802006-05-10 17:13:20 +0000474 def bpprint(self, out=None):
475 if out is None:
476 out = sys.stdout
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000477 if self.temporary:
Tim Peters11cf6052001-01-14 21:54:20 +0000478 disp = 'del '
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000479 else:
Tim Peters11cf6052001-01-14 21:54:20 +0000480 disp = 'keep '
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000481 if self.enabled:
Martin v. Löwis4b501e62006-04-15 08:41:11 +0000482 disp = disp + 'yes '
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000483 else:
Martin v. Löwis4b501e62006-04-15 08:41:11 +0000484 disp = disp + 'no '
Georg Brandl19564802006-05-10 17:13:20 +0000485 print >>out, '%-4dbreakpoint %s at %s:%d' % (self.number, disp,
486 self.file, self.line)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000487 if self.cond:
Georg Brandl19564802006-05-10 17:13:20 +0000488 print >>out, '\tstop only if %s' % (self.cond,)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000489 if self.ignore:
Georg Brandl19564802006-05-10 17:13:20 +0000490 print >>out, '\tignore next %d hits' % (self.ignore)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000491 if (self.hits):
492 if (self.hits > 1): ss = 's'
493 else: ss = ''
Georg Brandl19564802006-05-10 17:13:20 +0000494 print >>out, ('\tbreakpoint already hit %d time%s' %
495 (self.hits, ss))
Guido van Rossumd93643f1998-09-11 22:38:35 +0000496
497# -----------end of Breakpoint class----------
498
Johannes Gijsbers4a9faa12004-08-30 13:29:44 +0000499def checkfuncname(b, frame):
500 """Check whether we should break here because of `b.funcname`."""
501 if not b.funcname:
502 # Breakpoint was set via line number.
503 if b.line != frame.f_lineno:
504 # Breakpoint was set at a line with a def statement and the function
505 # defined is called: don't break.
506 return False
507 return True
508
509 # Breakpoint set via function name.
510
511 if frame.f_code.co_name != b.funcname:
512 # It's not a function call, but rather execution of def statement.
513 return False
514
515 # We are in the right frame.
516 if not b.func_first_executable_line:
517 # The function is entered for the 1st time.
518 b.func_first_executable_line = frame.f_lineno
519
520 if b.func_first_executable_line != frame.f_lineno:
521 # But we are not at the first line number: don't break.
522 return False
523 return True
524
Guido van Rossumd93643f1998-09-11 22:38:35 +0000525# Determines if there is an effective (active) breakpoint at this
526# line of code. Returns breakpoint number or 0 if none
527def effective(file, line, frame):
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000528 """Determine which breakpoint for this file:line is to be acted upon.
Guido van Rossumd93643f1998-09-11 22:38:35 +0000529
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000530 Called only if we know there is a bpt at this
531 location. Returns breakpoint that was triggered and a flag
532 that indicates if it is ok to delete a temporary bp.
Guido van Rossumd93643f1998-09-11 22:38:35 +0000533
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000534 """
535 possibles = Breakpoint.bplist[file,line]
536 for i in range(0, len(possibles)):
537 b = possibles[i]
538 if b.enabled == 0:
539 continue
Johannes Gijsbers4a9faa12004-08-30 13:29:44 +0000540 if not checkfuncname(b, frame):
541 continue
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000542 # Count every hit when bp is enabled
543 b.hits = b.hits + 1
544 if not b.cond:
545 # If unconditional, and ignoring,
546 # go on to next, else break
547 if b.ignore > 0:
548 b.ignore = b.ignore -1
549 continue
550 else:
551 # breakpoint and marker that's ok
552 # to delete if temporary
553 return (b,1)
554 else:
555 # Conditional bp.
556 # Ignore count applies only to those bpt hits where the
557 # condition evaluates to true.
558 try:
559 val = eval(b.cond, frame.f_globals,
Tim Peters11cf6052001-01-14 21:54:20 +0000560 frame.f_locals)
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000561 if val:
562 if b.ignore > 0:
563 b.ignore = b.ignore -1
564 # continue
565 else:
566 return (b,1)
567 # else:
568 # continue
569 except:
570 # if eval fails, most conservative
571 # thing is to stop on breakpoint
Tim Peters11cf6052001-01-14 21:54:20 +0000572 # regardless of ignore count.
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000573 # Don't delete temporary,
574 # as another hint to user.
575 return (b,0)
576 return (None, None)
Guido van Rossumd93643f1998-09-11 22:38:35 +0000577
Guido van Rossumbabe2bf1992-01-22 22:21:31 +0000578# -------------------- testing --------------------
579
580class Tdb(Bdb):
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000581 def user_call(self, frame, args):
582 name = frame.f_code.co_name
583 if not name: name = '???'
584 print '+++ call', name, args
585 def user_line(self, frame):
Eric S. Raymondb49f4a42001-02-09 05:07:04 +0000586 import linecache
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000587 name = frame.f_code.co_name
588 if not name: name = '???'
589 fn = self.canonic(frame.f_code.co_filename)
590 line = linecache.getline(fn, frame.f_lineno)
Eric S. Raymondb49f4a42001-02-09 05:07:04 +0000591 print '+++', fn, frame.f_lineno, name, ':', line.strip()
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000592 def user_return(self, frame, retval):
593 print '+++ return', retval
594 def user_exception(self, frame, exc_stuff):
595 print '+++ exception', exc_stuff
596 self.set_continue()
Guido van Rossumbabe2bf1992-01-22 22:21:31 +0000597
598def foo(n):
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000599 print 'foo(', n, ')'
600 x = bar(n*10)
601 print 'bar returned', x
Guido van Rossumbabe2bf1992-01-22 22:21:31 +0000602
603def bar(a):
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000604 print 'bar(', a, ')'
605 return a/2
Guido van Rossumbabe2bf1992-01-22 22:21:31 +0000606
607def test():
Guido van Rossum4acc25b2000-02-02 15:10:15 +0000608 t = Tdb()
609 t.run('import bdb; bdb.foo(10)')
Eric S. Raymondb49f4a42001-02-09 05:07:04 +0000610
611# end