blob: 789b57b4efaeaa91080a2bd71c2181bcc7868e73 [file] [log] [blame]
Guido van Rossum92df0c61992-01-14 18:30:15 +00001# pdb.py -- finally, a Python debugger! See below for instructions.
2
3
4# To do:
5# - Keep a list of exceptions trapped (default only KeyboardInterrupt?)
6# - It should be possible to intercept KeyboardInterrupt completely
7# - Handle return events differently (how?)
8# - When stopping on an exception, show traceback stack
9# - Merge with tb (for post-mortem usage)
10# - Show stack traces upside-down (like dbx/gdb) ???
11# (actually, the current way is more natural given the directions
12# taken by the up/down commands)
13
Guido van Rossum921c8241992-01-10 14:54:42 +000014
Guido van Rossumb9142571992-01-12 23:32:55 +000015# To use the debugger in its simplest form:
16# >>> import pdb
17# >>> pdb.run('<a statement>')
18# The debugger's prompt is '(Pdb) '.
19# This will stop in the first function call in <a statement>.
20
21# The commands recognized by the debugger are listed below.
22# Most can be abbreviated as indicated; e.g., h(elp) means that
23# 'help' can be typed as 'h' or 'help'
24# (but not as 'he' or 'hel', nor as 'H' or 'Help' or 'HELP').
25# Optional arguments are enclosed in square brackets.
26
27# A blank line repeats the previous command literally.
28# (Except for 'list', where it lists the next 11 lines.)
29
30# Commands that the debugger does not recognized are assumed to
31# be Python statements and are executed in the context of the
32# program being debugged.
33# Python statements can also be prefixed with an exclamation point ('!').
34# This is a powerful way to inspect the program being debugged;
35# it is even possible to change variables.
36# When an exception occurs in such a statement, the exception name
37# is printed but the debugger's state is not changed.
38
39# The debugger is not directly programmable; but it is implemented
40# as a class from which you can derive your own debugger class,
41# so you can make as fancy as you like.
42
43# The debugger's commands are:
44
45# h(elp)
46# Without argument, print the list of available commands.
47# With a command name as argument, print help about that command
48# (this is currently not implemented).
49
50# w(here)
51# Print a stack trace, with the most recent frame at the bottom.
52# An arrow indicates the "current frame", which determines the
53# context of most commands.
54
55# d(own)
56# Move the current frame one level down in the stack trace
57# (to an older frame).
58
59# u(p)
60# Move the current frame one level up in the stack trace
61# (to a newer frame).
62
63# b(reak) [lineno]
64# With a line number argument, set a break there in the current file.
65# Without argument, list all breaks.
66
67# cl(ear) [lineno]
68# With a line number argument, clear that break in the current file.
69# Without argument, clear all breaks (but first ask confirmation).
70
71# s(tep)
72# Execute the current line, stop at the first possible occasion
73# (either in a function that is called or in the current function).
74
75# n(ext)
76# Continue execution until the next line in the current function
77# is reached or it returns.
78
79# r(eturn)
80# Continue execution until the current function returns.
81
82# c(ont(inue))
83# Continue execution, only stop when a breakpoint is encountered.
84
85# l(ist) [first [,last]]
86# List source code for the current file.
87# Without arguments, list 11 lines around the current line
88# or continue the previous listing.
89# With one argument, list 11 lines starting at that line.
90# With two arguments, list the given range;
91# if the second argument is less than the first, it is a count.
92
93# a(rgs)
94# Print the argument list of the current function.
95
96# p expression
97# Print the value of the expression.
98
99# (!) statement
100# Execute the (one-line) statement in the context of
101# the current stack frame.
102# The exclamation point can be omitted unless the first word
103# of the statement resembles a debugger command.
104# To assign to a global variable you must always prefix the
105# command with a 'global' command, e.g.:
106# (Pdb) global list_options; list_options = ['-l']
107# (Pdb)
108
109# q(uit)
110# Quit from the debugger.
111# The program being executed is aborted.
112
113
114# Here's how it works.
115
116# Some changes were made to the interpreter:
117# - if sys.trace is defined (by the user), it should be a function
118# - sys.trace is called the global trace function
119# - there can also a local trace function (see later)
120
121# Trace functions have three arguments: (frame, event, arg)
122# - frame is the current stack frame
123# - event is a string: 'call', 'line', 'return' or 'exception'
124# - arg is dependent on the event type
125# A trace function should return a new trace function or None.
126# Class methods are accepted (and most useful!) as trace methods.
127
128# The events have the following meaning:
129#
130# 'call': A function is called (or some other code block entered).
131# The global trace function is called;
132# arg is the argument list to the function;
133# the return value specifies the local trace function.
134#
135# 'line': The interpreter is about to execute a new line of code
136# (sometimes multiple line events on one line exist).
137# The local trace function is called; arg in None;
138# the return value specifies the new local trace function.
139#
140# 'return': A function (or other code block) is about to return.
141# The local trace function is called;
142# arg is the value that will be returned.
143# The trace function's return value is ignored.
144#
145# 'exception': An exception has occurred.
146# The local trace function is called if there is one,
147# else the global trace function is called;
148# arg is a triple (exception, value, traceback);
149# the return value specifies the new local trace function
150#
151# Note that as an exception is propagated down the chain of callers,
152# an 'exception' event is generated at each level.
153
154# A stack frame object has the following read-only attributes:
155# f_code: the code object being executed
156# f_lineno: the current line number (-1 for 'call' events)
157# f_back: the stack frame of the caller, or None
158# f_locals: dictionary containing local name bindings
159# f_globals: dictionary containing global name bindings
160
161# A code object has the following read-only attributes:
162# co_code: the code string
163# co_names: the list of names used by the code
164# co_consts: the list of (literal) constants used by the code
165# co_filename: the filename from which the code was compiled
166
Guido van Rossum921c8241992-01-10 14:54:42 +0000167
168import string
169import sys
170import linecache
171
172
173# A generic class to build command interpreters
174
175PROMPT = '(Cmd) '
176IDENTCHARS = string.letters + string.digits + '_'
177
178class Cmd:
179 def init(self):
180 self.prompt = PROMPT
181 self.identchars = IDENTCHARS
Guido van Rossumb9142571992-01-12 23:32:55 +0000182 self.lastcmd = ''
Guido van Rossum921c8241992-01-10 14:54:42 +0000183 return self
Guido van Rossumb9142571992-01-12 23:32:55 +0000184 def cmdloop(self):
185 stop = None
186 while not stop:
187 try:
188 line = raw_input(self.prompt)
189 except EOFError:
190 line = 'EOF'
191 stop = self.onecmd(line)
192 return stop
193 def onecmd(self, line):
194 line = string.strip(line)
195 if not line:
196 line = self.lastcmd
197 print line
198 else:
199 self.lastcmd = line
Guido van Rossum921c8241992-01-10 14:54:42 +0000200 i, n = 0, len(line)
201 while i < n and line[i] in self.identchars: i = i+1
202 cmd, arg = line[:i], string.strip(line[i:])
203 if cmd == '':
Guido van Rossumb9142571992-01-12 23:32:55 +0000204 return self.default(line)
Guido van Rossum921c8241992-01-10 14:54:42 +0000205 else:
206 try:
207 func = eval('self.do_' + cmd)
208 except AttributeError:
Guido van Rossumb9142571992-01-12 23:32:55 +0000209 return self.default(line)
210 return func(arg)
Guido van Rossum921c8241992-01-10 14:54:42 +0000211 def default(self, line):
212 print '*** Unknown syntax:', line
213 def do_help(self, arg):
214 if arg:
215 # XXX check arg syntax
216 try:
217 func = eval('self.help_' + arg)
218 except:
219 print '*** No help on', `arg`
220 return
221 func()
222 else:
223 import getattr
224 names = getattr.dir(self)
225 cmds = []
226 for name in names:
227 if name[:3] == 'do_':
228 cmds.append(name[3:])
229 print cmds
230
231
232# A specialization of Cmd for use by the debugger
233
Guido van Rossumb9142571992-01-12 23:32:55 +0000234PdbQuit = 'pdb.PdbQuit' # Exception to give up
Guido van Rossum921c8241992-01-10 14:54:42 +0000235
236class Pdb(Cmd):
237
238 def init(self):
239 self = Cmd.init(self)
240 self.prompt = '(Pdb) '
241 self.reset()
Guido van Rossum921c8241992-01-10 14:54:42 +0000242 return self
243
244 def reset(self):
Guido van Rossumb9142571992-01-12 23:32:55 +0000245 self.breaks = {}
Guido van Rossum921c8241992-01-10 14:54:42 +0000246 self.botframe = None
Guido van Rossumb9142571992-01-12 23:32:55 +0000247 self.stopframe = None
Guido van Rossum921c8241992-01-10 14:54:42 +0000248 self.forget()
249
250 def forget(self):
Guido van Rossumb9142571992-01-12 23:32:55 +0000251 self.setup(None)
Guido van Rossum921c8241992-01-10 14:54:42 +0000252
253 def setup(self, frame):
254 self.curframe = self.topframe = frame
255 self.stack = []
256 self.lineno = None
Guido van Rossum921c8241992-01-10 14:54:42 +0000257
258 def run(self, cmd):
Guido van Rossumb9142571992-01-12 23:32:55 +0000259 import __main__
260 dict = __main__.__dict__
261 self.runctx(cmd, dict, dict)
262
263 def runctx(self, cmd, globals, locals):
Guido van Rossum921c8241992-01-10 14:54:42 +0000264 self.reset()
265 sys.trace = self.dispatch
266 try:
Guido van Rossumb9142571992-01-12 23:32:55 +0000267 exec(cmd + '\n', globals, locals)
Guido van Rossum921c8241992-01-10 14:54:42 +0000268 except PdbQuit:
269 pass
270 finally:
271 sys.trace = None
272 del sys.trace
273 self.reset()
274
Guido van Rossumb9142571992-01-12 23:32:55 +0000275 def dispatch(self, frame, event, arg):
276 if event == 'line':
277 return self.dispatch_line(frame)
278 if event == 'call':
279 return self.dispatch_call(frame, arg)
280 if event == 'return':
281 return self.dispatch_return(frame, arg)
282 if event == 'exception':
283 return self.dispatch_exception(frame, arg)
284 print '*** dispatch: unknown event type', `event`
Guido van Rossum921c8241992-01-10 14:54:42 +0000285 return self.dispatch
286
Guido van Rossumb9142571992-01-12 23:32:55 +0000287 def dispatch_line(self, frame):
288 if self.stop_here(frame) or self.break_here(frame):
289 self.ask_user(frame)
290 return self.dispatch
291
292 def dispatch_call(self, frame, arg):
293 if self.botframe is None:
294 self.botframe = frame
295 return
296 if not (self.stop_here(frame) or self.break_anywhere(frame)):
297 return
298 frame.f_locals['__args__'] = arg
299 return self.dispatch
300
301 def dispatch_return(self, frame, arg):
302 if self.stop_here(frame):
303 print '!!! return', `arg`
304 return
305
306 def dispatch_exception(self, frame, arg):
307 if arg[0] is PdbQuit: return None
308 if self.stop_here(frame):
309 print '!!! exception', arg[0] + ':', `arg[1]`
310 self.ask_user(frame)
311 return self.dispatch
312
313 def stop_here(self, frame):
314 if self.stopframe is None:
315 return 1
316 if frame is self.stopframe:
317 return 1
318 while frame is not self.stopframe:
319 if frame is None:
320 return 1
321 frame = frame.f_back
322 return 0
323
324 def break_here(self, frame):
325 if not self.breaks.has_key(frame.f_code.co_filename):
326 return 0
327 if not frame.f_lineno in \
328 self.breaks[frame.f_code.co_filename]:
329 return 0
330 return 1
331
332 def break_anywhere(self, frame):
333 return self.breaks.has_key(frame.f_code.co_filename)
334
335 def ask_user(self, frame):
336 self.setup(frame)
Guido van Rossum921c8241992-01-10 14:54:42 +0000337 self.printwhere(self.curframe)
Guido van Rossumb9142571992-01-12 23:32:55 +0000338 dummy = self.cmdloop()
339 self.forget()
Guido van Rossum921c8241992-01-10 14:54:42 +0000340
341 def default(self, line):
342 if not line:
Guido van Rossumb9142571992-01-12 23:32:55 +0000343 return self.do_next('')
Guido van Rossum921c8241992-01-10 14:54:42 +0000344 else:
345 if line[0] == '!': line = line[1:]
346 try:
347 exec(line + '\n', \
348 self.curframe.f_globals, \
349 self.curframe.f_locals)
350 except:
Guido van Rossumb9142571992-01-12 23:32:55 +0000351 print '***', sys.exc_type + ':',
Guido van Rossum921c8241992-01-10 14:54:42 +0000352 print `sys.exc_value`
353
354 do_h = Cmd.do_help
355
356 def do_break(self, arg):
357 if not arg:
358 print self.breaks # XXX
359 return
360 try:
361 lineno = int(eval(arg))
362 except:
363 print '*** Error in argument:', `arg`
364 return
365 filename = self.curframe.f_code.co_filename
366 line = linecache.getline(filename, lineno)
367 if not line:
368 print '*** That line does not exist!'
369 return
370 if not self.breaks.has_key(filename):
371 self.breaks[filename] = []
372 list = self.breaks[filename]
373 if lineno in list:
374 print '*** There is already a break there!'
375 return
376 list.append(lineno)
377 do_b = do_break
378
379 def do_clear(self, arg):
380 if not arg:
Guido van Rossumb9142571992-01-12 23:32:55 +0000381 try:
382 reply = raw_input('Clear all breaks? ')
383 except EOFError:
384 reply = 'no'
385 reply = string.lower(string.strip(reply))
386 if reply in ('y', 'yes'):
387 self.breaks = {}
Guido van Rossum921c8241992-01-10 14:54:42 +0000388 return
389 try:
390 lineno = int(eval(arg))
391 except:
392 print '*** Error in argument:', `arg`
393 return
394 filename = self.curframe.f_code.co_filename
395 try:
396 self.breaks[filename].remove(lineno)
Guido van Rossum921c8241992-01-10 14:54:42 +0000397 except (ValueError, KeyError):
398 print '*** There is no break there!'
399 return
Guido van Rossumb9142571992-01-12 23:32:55 +0000400 if not self.breaks[filename]:
401 del self.breaks[filename]
402 do_cl = do_clear # 'c' is already an abbreviation for 'continue'
Guido van Rossum921c8241992-01-10 14:54:42 +0000403
404 def do_where(self, arg):
405 self.printtb()
406 do_w = do_where
407
408 def do_up(self, arg):
Guido van Rossum921c8241992-01-10 14:54:42 +0000409 if self.curframe == self.botframe or \
Guido van Rossumb9142571992-01-12 23:32:55 +0000410 not self.curframe.f_back: print '*** Top'
Guido van Rossum921c8241992-01-10 14:54:42 +0000411 else:
412 self.stack.append(self.curframe)
413 self.curframe = self.curframe.f_back
414 self.lineno = None
415 self.printwhere(self.curframe)
Guido van Rossumb9142571992-01-12 23:32:55 +0000416 do_u = do_up
417
418 def do_down(self, arg):
419 if not self.stack: print '*** Bottom'
420 else:
421 self.curframe = self.stack[-1]
422 self.lineno = None
423 del self.stack[-1]
424 self.printwhere(self.curframe)
Guido van Rossum921c8241992-01-10 14:54:42 +0000425 do_d = do_down
426
427 def do_step(self, arg):
Guido van Rossumb9142571992-01-12 23:32:55 +0000428 self.stopframe = None
429 return 1
Guido van Rossum921c8241992-01-10 14:54:42 +0000430 do_s = do_step
431
432 def do_next(self, arg):
Guido van Rossumb9142571992-01-12 23:32:55 +0000433 self.stopframe = self.curframe
434 return 1
Guido van Rossum921c8241992-01-10 14:54:42 +0000435 do_n = do_next
436
Guido van Rossumb9142571992-01-12 23:32:55 +0000437 def do_return(self, arg):
438 self.stopframe = self.curframe.f_back
439 return 1
440 do_r = do_return
441
Guido van Rossum921c8241992-01-10 14:54:42 +0000442 def do_continue(self, arg):
Guido van Rossumb9142571992-01-12 23:32:55 +0000443 self.stopframe = self.botframe
444 return 1
Guido van Rossum921c8241992-01-10 14:54:42 +0000445 do_c = do_cont = do_continue
446
447 def do_quit(self, arg):
Guido van Rossumb9142571992-01-12 23:32:55 +0000448 self.stopframe = self.botframe
449 raise PdbQuit
Guido van Rossum921c8241992-01-10 14:54:42 +0000450 do_q = do_quit
451
452 def do_list(self, arg):
Guido van Rossumb9142571992-01-12 23:32:55 +0000453 self.lastcmd = 'list'
Guido van Rossum921c8241992-01-10 14:54:42 +0000454 last = None
455 if arg:
456 try:
457 x = eval(arg, {}, {})
458 if type(x) == type(()):
459 first, last = x
460 first = int(first)
461 last = int(last)
462 if last < first:
463 # Assume it's a count
464 last = first + last
465 else:
466 first = int(x)
467 except:
468 print '*** Error in argument:', `arg`
469 return
470 elif self.lineno is None:
471 first = max(1, self.curframe.f_lineno - 5)
472 else:
473 first = self.lineno + 1
474 if last is None:
475 last = first + 10
476 filename = self.curframe.f_code.co_filename
477 if self.breaks.has_key(filename):
478 breaklist = self.breaks[filename]
479 else:
480 breaklist = []
481 try:
482 for lineno in range(first, last+1):
483 line = linecache.getline(filename, lineno)
484 if not line:
485 print '[EOF]'
486 break
487 else:
488 s = string.rjust(`lineno`, 3)
489 if len(s) < 4: s = s + ' '
490 if lineno in breaklist: s = s + 'B'
491 else: s = s + ' '
492 if lineno == self.curframe.f_lineno:
493 s = s + '->'
494 print s + '\t' + line,
495 self.lineno = lineno
496 except KeyboardInterrupt:
497 pass
498 do_l = do_list
Guido van Rossumb9142571992-01-12 23:32:55 +0000499
500 def do_args(self, arg):
501 try:
502 value = eval('__args__', self.curframe.f_globals, \
503 self.curframe.f_locals)
504 except:
505 print '***', sys.exc_type + ':', `sys.exc_value`
506 return
507 print `value`
508 do_a = do_args
509
510 def do_p(self, arg):
511 try:
512 value = eval(arg, self.curframe.f_globals, \
513 self.curframe.f_locals)
514 except:
515 print '***', sys.exc_type + ':', `sys.exc_value`
516 return
517 print `value`
Guido van Rossum921c8241992-01-10 14:54:42 +0000518
519 # Print a traceback starting at a given stack frame
520 # Note that it is printed upside-down with respect
521 # to the orientation suggested by the up/down commands.
522 # This is consistent with gdb.
523 def printtb(self):
524 list = []
525 frame = self.topframe
526 while frame:
527 list.append(frame)
528 if frame is self.botframe: break
529 frame = frame.f_back
530 list.reverse()
531 for frame in list:
532 self.printwhere(frame)
533
534 def printwhere(self, frame):
535 if frame is self.curframe: print '->',
536 code = frame.f_code
537 filename = code.co_filename
538 lineno = frame.f_lineno
539 print filename + '(' + `lineno` + ')',
540 line = linecache.getline(filename, lineno)
541 if line: print string.strip(line),
542 print
543
544
545# --------------------- testing ---------------------
546
547# The Ackermann function -- a highly recursive beast
548cheat = 0
549cache = {}
550def ack(x, y):
551 key = `(long(x), long(y))`
552 if cache.has_key(key):
553 res = cache[key]
554 else:
555 if x == 0:
556 res = 1L
557 elif y == 0:
558 if x == 1:
559 res = 2L
560 else:
561 res = 2L + x
562 elif y == 1 and cheat >= 1:
563 res = 2L * x
564 elif y == 2 and cheat >= 2:
565 res = pow(2L, x)
566 else:
567 res = ack(ack(x-1, y), y-1)
568 cache[key] = res
569 return res
570
571def foo(n):
572 print 'foo', n
573 x = bar(n*2)
574 print 'bar returned', x
575 return
576
577def bar(a):
578 print 'bar', a
579 return a*10
580
581def test():
582 linecache.checkcache()
Guido van Rossumb9142571992-01-12 23:32:55 +0000583 Pdb().init().run('foo(12)\n')
Guido van Rossum921c8241992-01-10 14:54:42 +0000584
585
586# --------------------- main ---------------------
587
588import os
589
590def main():
591 if sys.argv[1:]:
592 file = sys.argv[1]
593 head, tail = os.path.split(file)
594 if tail[-3:] != '.py':
595 print 'Sorry, file arg must be a python module'
596 print '(i.e., must end in \'.py\')'
597 # XXX Or we could copy it to a temp file
598 sys.exit(2)
599 del sys.argv[0]
600 sys.path.insert(0, head)
Guido van Rossumb9142571992-01-12 23:32:55 +0000601 run('import ' + tail[:-3])
Guido van Rossum921c8241992-01-10 14:54:42 +0000602 else:
Guido van Rossumb9142571992-01-12 23:32:55 +0000603 run('')
604
605def run(statement):
606 Pdb().init().run(statement)