Issue #3809: Fixed spurious 'test.blah' file left behind by test_logging.
[python.git] / Lib / bdb.py
blobd74415bf14771fd29777e7ece80654777d4552a6
1 """Debugger basics"""
3 import sys
4 import os
5 import types
7 __all__ = ["BdbQuit","Bdb","Breakpoint"]
9 class BdbQuit(Exception):
10 """Exception to give up completely"""
13 class Bdb:
15 """Generic Python debugger base class.
17 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 """
22 def __init__(self):
23 self.breaks = {}
24 self.fncache = {}
26 def canonic(self, filename):
27 if filename == "<" + filename[1:-1] + ">":
28 return filename
29 canonic = self.fncache.get(filename)
30 if not canonic:
31 canonic = os.path.abspath(filename)
32 canonic = os.path.normcase(canonic)
33 self.fncache[filename] = canonic
34 return canonic
36 def reset(self):
37 import linecache
38 linecache.checkcache()
39 self.botframe = None
40 self._set_stopinfo(None, None)
42 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)
53 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
59 print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event)
60 return self.trace_dispatch
62 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
68 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()
72 self.botframe = frame.f_back # (CT) Note that this may also be None!
73 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
81 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
85 return self.trace_dispatch
87 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
93 # 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.
97 def stop_here(self, frame):
98 # (CT) stopframe may now also be None, see dispatch_call.
99 # (CT) the former test for None is therefore removed from here.
100 if frame is self.stopframe:
101 return frame.f_lineno >= self.stoplineno
102 while frame is not None and frame is not self.stopframe:
103 if frame is self.botframe:
104 return True
105 frame = frame.f_back
106 return False
108 def break_here(self, frame):
109 filename = self.canonic(frame.f_code.co_filename)
110 if not filename in self.breaks:
111 return False
112 lineno = frame.f_lineno
113 if not lineno in self.breaks[filename]:
114 # 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
120 # 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))
126 return True
127 else:
128 return False
130 def do_clear(self, arg):
131 raise NotImplementedError, "subclass of bdb must implement do_clear()"
133 def break_anywhere(self, frame):
134 return self.canonic(frame.f_code.co_filename) in self.breaks
136 # Derived classes should override the user_* methods
137 # to gain control.
139 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
144 def user_line(self, frame):
145 """This method is called when we stop or break at this line."""
146 pass
148 def user_return(self, frame, return_value):
149 """This method is called when a return trap is set here."""
150 pass
152 def user_exception(self, frame, exc_info):
153 exc_type, exc_value, exc_traceback = exc_info
154 """This method is called if an exception occurs,
155 but only if we are to stop at or just below this level."""
156 pass
158 def _set_stopinfo(self, stopframe, returnframe, stoplineno=-1):
159 self.stopframe = stopframe
160 self.returnframe = returnframe
161 self.quitting = 0
162 self.stoplineno = stoplineno
164 # Derived classes and clients can call the following methods
165 # to affect the stepping state.
167 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)
172 def set_step(self):
173 """Stop after one line of code."""
174 self._set_stopinfo(None,None)
176 def set_next(self, frame):
177 """Stop on the next line in or below the given frame."""
178 self._set_stopinfo(frame, None)
180 def set_return(self, frame):
181 """Stop when returning from the given frame."""
182 self._set_stopinfo(frame.f_back, frame)
184 def set_trace(self, frame=None):
185 """Start debugging from `frame`.
187 If frame is not specified, debugging starts from caller's frame.
189 if frame is None:
190 frame = sys._getframe().f_back
191 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)
199 def set_continue(self):
200 # Don't stop except at breakpoints or when finished
201 self._set_stopinfo(self.botframe, None)
202 if not self.breaks:
203 # no breakpoints; run without debugger overhead
204 sys.settrace(None)
205 frame = sys._getframe().f_back
206 while frame and frame is not self.botframe:
207 del frame.f_trace
208 frame = frame.f_back
210 def set_quit(self):
211 self.stopframe = self.botframe
212 self.returnframe = None
213 self.quitting = 1
214 sys.settrace(None)
216 # 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().
223 def set_break(self, filename, lineno, temporary=0, cond = None,
224 funcname=None):
225 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)
231 if not filename in self.breaks:
232 self.breaks[filename] = []
233 list = self.breaks[filename]
234 if not lineno in list:
235 list.append(lineno)
236 bp = Breakpoint(filename, lineno, temporary, cond, funcname)
238 def clear_break(self, filename, lineno):
239 filename = self.canonic(filename)
240 if not filename in self.breaks:
241 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]
254 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)
267 def clear_all_file_breaks(self, filename):
268 filename = self.canonic(filename)
269 if not filename in self.breaks:
270 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]
277 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 = {}
285 def get_break(self, filename, lineno):
286 filename = self.canonic(filename)
287 return filename in self.breaks and \
288 lineno in self.breaks[filename]
290 def get_breaks(self, filename, lineno):
291 filename = self.canonic(filename)
292 return filename in self.breaks and \
293 lineno in self.breaks[filename] and \
294 Breakpoint.bplist[filename, lineno] or []
296 def get_file_breaks(self, filename):
297 filename = self.canonic(filename)
298 if filename in self.breaks:
299 return self.breaks[filename]
300 else:
301 return []
303 def get_all_breaks(self):
304 return self.breaks
306 # Derived classes and clients can call the following method
307 # to get a data structure representing a stack trace.
309 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
327 def format_stack_entry(self, frame_lineno, lprefix=': '):
328 import linecache, repr
329 frame, lineno = frame_lineno
330 filename = self.canonic(frame.f_code.co_filename)
331 s = '%s(%r)' % (filename, lineno)
332 if frame.f_code.co_name:
333 s = s + frame.f_code.co_name
334 else:
335 s = s + "<lambda>"
336 if '__args__' in frame.f_locals:
337 args = frame.f_locals['__args__']
338 else:
339 args = None
340 if args:
341 s = s + repr.repr(args)
342 else:
343 s = s + '()'
344 if '__return__' in frame.f_locals:
345 rv = frame.f_locals['__return__']
346 s = s + '->'
347 s = s + repr.repr(rv)
348 line = linecache.getline(filename, lineno)
349 if line: s = s + lprefix + line.strip()
350 return s
352 # The following two methods can be called by clients to use
353 # a debugger to debug a statement, given as a string.
355 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:
366 exec cmd in globals, locals
367 except BdbQuit:
368 pass
369 finally:
370 self.quitting = 1
371 sys.settrace(None)
373 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:
384 return eval(expr, globals, locals)
385 except BdbQuit:
386 pass
387 finally:
388 self.quitting = 1
389 sys.settrace(None)
391 def runctx(self, cmd, globals, locals):
392 # B/W compatibility
393 self.run(cmd, globals, locals)
395 # This method is more useful to debug a single function call.
397 def runcall(self, func, *args, **kwds):
398 self.reset()
399 sys.settrace(self.trace_dispatch)
400 res = None
401 try:
402 res = func(*args, **kwds)
403 except BdbQuit:
404 pass
405 finally:
406 self.quitting = 1
407 sys.settrace(None)
408 return res
411 def set_trace():
412 Bdb().set_trace()
415 class Breakpoint:
417 """Breakpoint class
419 Implements temporary breakpoints, ignore counts, disabling and
420 (re)-enabling, and conditionals.
422 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.
430 # XXX Keeping state in the class is a mistake -- this means
431 # you cannot have more than one active Bdb instance.
433 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()
439 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
443 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]
460 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]
468 def enable(self):
469 self.enabled = 1
471 def disable(self):
472 self.enabled = 0
474 def bpprint(self, out=None):
475 if out is None:
476 out = sys.stdout
477 if self.temporary:
478 disp = 'del '
479 else:
480 disp = 'keep '
481 if self.enabled:
482 disp = disp + 'yes '
483 else:
484 disp = disp + 'no '
485 print >>out, '%-4dbreakpoint %s at %s:%d' % (self.number, disp,
486 self.file, self.line)
487 if self.cond:
488 print >>out, '\tstop only if %s' % (self.cond,)
489 if self.ignore:
490 print >>out, '\tignore next %d hits' % (self.ignore)
491 if (self.hits):
492 if (self.hits > 1): ss = 's'
493 else: ss = ''
494 print >>out, ('\tbreakpoint already hit %d time%s' %
495 (self.hits, ss))
497 # -----------end of Breakpoint class----------
499 def 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
509 # Breakpoint set via function name.
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
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
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
525 # Determines if there is an effective (active) breakpoint at this
526 # line of code. Returns breakpoint number or 0 if none
527 def effective(file, line, frame):
528 """Determine which breakpoint for this file:line is to be acted upon.
530 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.
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
540 if not checkfuncname(b, frame):
541 continue
542 # 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,
560 frame.f_locals)
561 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
572 # regardless of ignore count.
573 # Don't delete temporary,
574 # as another hint to user.
575 return (b,0)
576 return (None, None)
578 # -------------------- testing --------------------
580 class Tdb(Bdb):
581 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):
586 import linecache
587 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)
591 print '+++', fn, frame.f_lineno, name, ':', line.strip()
592 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()
598 def foo(n):
599 print 'foo(', n, ')'
600 x = bar(n*10)
601 print 'bar returned', x
603 def bar(a):
604 print 'bar(', a, ')'
605 return a/2
607 def test():
608 t = Tdb()
609 t.run('import bdb; bdb.foo(10)')
611 # end