blob: 30b1477536d7a904eb0ffd69a7d1eb3f1ecd6361 [file] [log] [blame]
Guido van Rossum6fe08b01992-01-16 13:50:21 +00001# pdb.py -- finally, a Python debugger!
Guido van Rossum92df0c61992-01-14 18:30:15 +00002
Guido van Rossum23efba41992-01-27 16:58:47 +00003# (See pdb.doc for documentation.)
Guido van Rossum921c8241992-01-10 14:54:42 +00004
5import string
6import sys
7import linecache
Guido van Rossum23efba41992-01-27 16:58:47 +00008import cmd
9import bdb
10import repr
Guido van Rossum921c8241992-01-10 14:54:42 +000011
12
Guido van Rossuma558e371994-11-10 22:27:35 +000013# Interaction prompt line will separate file and call info from code
14# text using value of line_prefix string. A newline and arrow may
15# be to your liking. You can set it once pdb is imported using the
16# command "pdb.line_prefix = '\n% '".
17# line_prefix = ': ' # Use this to get the old situation back
18line_prefix = '\n-> ' # Probably a better default
19
Guido van Rossum23efba41992-01-27 16:58:47 +000020class Pdb(bdb.Bdb, cmd.Cmd):
Guido van Rossum921c8241992-01-10 14:54:42 +000021
Guido van Rossum5ef74b81993-06-23 11:55:24 +000022 def __init__(self):
23 bdb.Bdb.__init__(self)
24 cmd.Cmd.__init__(self)
Guido van Rossum921c8241992-01-10 14:54:42 +000025 self.prompt = '(Pdb) '
Guido van Rossum921c8241992-01-10 14:54:42 +000026
27 def reset(self):
Guido van Rossum23efba41992-01-27 16:58:47 +000028 bdb.Bdb.reset(self)
Guido van Rossum921c8241992-01-10 14:54:42 +000029 self.forget()
30
31 def forget(self):
Guido van Rossum921c8241992-01-10 14:54:42 +000032 self.lineno = None
Guido van Rossum6fe08b01992-01-16 13:50:21 +000033 self.stack = []
Guido van Rossum7ac1c811992-01-16 13:55:21 +000034 self.curindex = 0
35 self.curframe = None
Guido van Rossum23efba41992-01-27 16:58:47 +000036
37 def setup(self, f, t):
38 self.forget()
39 self.stack, self.curindex = self.get_stack(f, t)
Guido van Rossum7ac1c811992-01-16 13:55:21 +000040 self.curframe = self.stack[self.curindex][0]
Guido van Rossum921c8241992-01-10 14:54:42 +000041
Guido van Rossum23efba41992-01-27 16:58:47 +000042 # Override Bdb methods (except user_call, for now)
Guido van Rossumb9142571992-01-12 23:32:55 +000043
Guido van Rossum23efba41992-01-27 16:58:47 +000044 def user_line(self, frame):
45 # This function is called when we stop or break at this line
46 self.interaction(frame, None)
Guido van Rossum7ac1c811992-01-16 13:55:21 +000047
Guido van Rossum23efba41992-01-27 16:58:47 +000048 def user_return(self, frame, return_value):
49 # This function is called when a return trap is set here
50 frame.f_locals['__return__'] = return_value
51 print '--Return--'
52 self.interaction(frame, None)
Guido van Rossum921c8241992-01-10 14:54:42 +000053
Guido van Rossum23efba41992-01-27 16:58:47 +000054 def user_exception(self, frame, (exc_type, exc_value, exc_traceback)):
55 # This function is called if an exception occurs,
56 # but only if we are to stop at or just below this level
57 frame.f_locals['__exception__'] = exc_type, exc_value
58 print exc_type + ':', repr.repr(exc_value)
59 self.interaction(frame, exc_traceback)
Guido van Rossum921c8241992-01-10 14:54:42 +000060
Guido van Rossum23efba41992-01-27 16:58:47 +000061 # General interaction function
Guido van Rossumb9142571992-01-12 23:32:55 +000062
Guido van Rossum23efba41992-01-27 16:58:47 +000063 def interaction(self, frame, traceback):
Guido van Rossum6fe08b01992-01-16 13:50:21 +000064 self.setup(frame, traceback)
Guido van Rossuma558e371994-11-10 22:27:35 +000065 self.print_stack_entry(self.stack[self.curindex],
66 line_prefix)
Guido van Rossum6fe08b01992-01-16 13:50:21 +000067 self.cmdloop()
Guido van Rossumb9142571992-01-12 23:32:55 +000068 self.forget()
Guido van Rossum23efba41992-01-27 16:58:47 +000069
Guido van Rossum921c8241992-01-10 14:54:42 +000070 def default(self, line):
Guido van Rossum23efba41992-01-27 16:58:47 +000071 if line[:1] == '!': line = line[1:]
72 locals = self.curframe.f_locals
73 globals = self.curframe.f_globals
Guido van Rossum8e2ec561993-07-29 09:37:38 +000074 globals['__privileged__'] = 1
Guido van Rossum23efba41992-01-27 16:58:47 +000075 try:
76 exec(line + '\n', globals, locals)
77 except:
78 print '***', sys.exc_type + ':', sys.exc_value
79
80 # Command definitions, called by cmdloop()
81 # The argument is the remaining string on the command line
82 # Return true to exit from the command loop
Guido van Rossum921c8241992-01-10 14:54:42 +000083
Guido van Rossum23efba41992-01-27 16:58:47 +000084 do_h = cmd.Cmd.do_help
Guido van Rossumb6775db1994-08-01 11:34:53 +000085
Guido van Rossum921c8241992-01-10 14:54:42 +000086 def do_break(self, arg):
87 if not arg:
Guido van Rossum23efba41992-01-27 16:58:47 +000088 print self.get_all_breaks() # XXX
Guido van Rossum921c8241992-01-10 14:54:42 +000089 return
Guido van Rossumb6775db1994-08-01 11:34:53 +000090 # Try line number as argument
91 try:
Guido van Rossum921c8241992-01-10 14:54:42 +000092 lineno = int(eval(arg))
Guido van Rossumb6775db1994-08-01 11:34:53 +000093 filename = self.curframe.f_code.co_filename
Guido van Rossum921c8241992-01-10 14:54:42 +000094 except:
Guido van Rossumb6775db1994-08-01 11:34:53 +000095 # Try function name as the argument
96 import codehack
97 try:
98 func = eval(arg, self.curframe.f_globals,
99 self.curframe.f_locals)
100 if hasattr(func, 'im_func'):
101 func = func.im_func
102 code = func.func_code
103 except:
104 print '*** Could not eval argument:', arg
105 return
106 lineno = codehack.getlineno(code)
107 filename = code.co_filename
108
109 # now set the break point
Guido van Rossum23efba41992-01-27 16:58:47 +0000110 err = self.set_break(filename, lineno)
111 if err: print '***', err
Guido van Rossum921c8241992-01-10 14:54:42 +0000112 do_b = do_break
113
114 def do_clear(self, arg):
115 if not arg:
Guido van Rossumb9142571992-01-12 23:32:55 +0000116 try:
117 reply = raw_input('Clear all breaks? ')
118 except EOFError:
119 reply = 'no'
120 reply = string.lower(string.strip(reply))
121 if reply in ('y', 'yes'):
Guido van Rossum23efba41992-01-27 16:58:47 +0000122 self.clear_all_breaks()
Guido van Rossum921c8241992-01-10 14:54:42 +0000123 return
124 try:
125 lineno = int(eval(arg))
126 except:
127 print '*** Error in argument:', `arg`
128 return
129 filename = self.curframe.f_code.co_filename
Guido van Rossum89a78691992-12-14 12:57:56 +0000130 err = self.clear_break(filename, lineno)
Guido van Rossum23efba41992-01-27 16:58:47 +0000131 if err: print '***', err
Guido van Rossumb9142571992-01-12 23:32:55 +0000132 do_cl = do_clear # 'c' is already an abbreviation for 'continue'
Guido van Rossum921c8241992-01-10 14:54:42 +0000133
134 def do_where(self, arg):
Guido van Rossum23efba41992-01-27 16:58:47 +0000135 self.print_stack_trace()
Guido van Rossum921c8241992-01-10 14:54:42 +0000136 do_w = do_where
137
138 def do_up(self, arg):
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000139 if self.curindex == 0:
140 print '*** Oldest frame'
Guido van Rossum921c8241992-01-10 14:54:42 +0000141 else:
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000142 self.curindex = self.curindex - 1
143 self.curframe = self.stack[self.curindex][0]
Guido van Rossum23efba41992-01-27 16:58:47 +0000144 self.print_stack_entry(self.stack[self.curindex])
Guido van Rossumc629d341992-11-05 10:43:02 +0000145 self.lineno = None
Guido van Rossumb9142571992-01-12 23:32:55 +0000146 do_u = do_up
147
148 def do_down(self, arg):
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000149 if self.curindex + 1 == len(self.stack):
150 print '*** Newest frame'
Guido van Rossumb9142571992-01-12 23:32:55 +0000151 else:
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000152 self.curindex = self.curindex + 1
153 self.curframe = self.stack[self.curindex][0]
Guido van Rossum23efba41992-01-27 16:58:47 +0000154 self.print_stack_entry(self.stack[self.curindex])
Guido van Rossumc629d341992-11-05 10:43:02 +0000155 self.lineno = None
Guido van Rossum921c8241992-01-10 14:54:42 +0000156 do_d = do_down
157
158 def do_step(self, arg):
Guido van Rossum23efba41992-01-27 16:58:47 +0000159 self.set_step()
Guido van Rossumb9142571992-01-12 23:32:55 +0000160 return 1
Guido van Rossum921c8241992-01-10 14:54:42 +0000161 do_s = do_step
162
163 def do_next(self, arg):
Guido van Rossum23efba41992-01-27 16:58:47 +0000164 self.set_next(self.curframe)
Guido van Rossumb9142571992-01-12 23:32:55 +0000165 return 1
Guido van Rossum921c8241992-01-10 14:54:42 +0000166 do_n = do_next
167
Guido van Rossumb9142571992-01-12 23:32:55 +0000168 def do_return(self, arg):
Guido van Rossum23efba41992-01-27 16:58:47 +0000169 self.set_return(self.curframe)
Guido van Rossumb9142571992-01-12 23:32:55 +0000170 return 1
171 do_r = do_return
172
Guido van Rossum921c8241992-01-10 14:54:42 +0000173 def do_continue(self, arg):
Guido van Rossum23efba41992-01-27 16:58:47 +0000174 self.set_continue()
Guido van Rossumb9142571992-01-12 23:32:55 +0000175 return 1
Guido van Rossum921c8241992-01-10 14:54:42 +0000176 do_c = do_cont = do_continue
177
178 def do_quit(self, arg):
Guido van Rossum23efba41992-01-27 16:58:47 +0000179 self.set_quit()
180 return 1
Guido van Rossum921c8241992-01-10 14:54:42 +0000181 do_q = do_quit
182
Guido van Rossum23efba41992-01-27 16:58:47 +0000183 def do_args(self, arg):
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184 if self.curframe.f_locals.has_key('__args__'):
185 print `self.curframe.f_locals['__args__']`
Guido van Rossum23efba41992-01-27 16:58:47 +0000186 else:
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187 print '*** No arguments?!'
Guido van Rossum23efba41992-01-27 16:58:47 +0000188 do_a = do_args
189
190 def do_retval(self, arg):
191 if self.curframe.f_locals.has_key('__return__'):
192 print self.curframe.f_locals['__return__']
193 else:
194 print '*** Not yet returned!'
195 do_rv = do_retval
196
197 def do_p(self, arg):
Guido van Rossum8e2ec561993-07-29 09:37:38 +0000198 self.curframe.f_globals['__privileged__'] = 1
Guido van Rossum23efba41992-01-27 16:58:47 +0000199 try:
200 value = eval(arg, self.curframe.f_globals, \
201 self.curframe.f_locals)
202 except:
203 print '***', sys.exc_type + ':', `sys.exc_value`
204 return
Guido van Rossum8e2ec561993-07-29 09:37:38 +0000205
Guido van Rossum23efba41992-01-27 16:58:47 +0000206 print `value`
207
Guido van Rossum921c8241992-01-10 14:54:42 +0000208 def do_list(self, arg):
Guido van Rossumb9142571992-01-12 23:32:55 +0000209 self.lastcmd = 'list'
Guido van Rossum921c8241992-01-10 14:54:42 +0000210 last = None
211 if arg:
212 try:
213 x = eval(arg, {}, {})
214 if type(x) == type(()):
215 first, last = x
216 first = int(first)
217 last = int(last)
218 if last < first:
219 # Assume it's a count
220 last = first + last
221 else:
Guido van Rossumc629d341992-11-05 10:43:02 +0000222 first = max(1, int(x) - 5)
Guido van Rossum921c8241992-01-10 14:54:42 +0000223 except:
224 print '*** Error in argument:', `arg`
225 return
226 elif self.lineno is None:
227 first = max(1, self.curframe.f_lineno - 5)
228 else:
229 first = self.lineno + 1
Guido van Rossumc629d341992-11-05 10:43:02 +0000230 if last == None:
Guido van Rossum921c8241992-01-10 14:54:42 +0000231 last = first + 10
232 filename = self.curframe.f_code.co_filename
Guido van Rossum23efba41992-01-27 16:58:47 +0000233 breaklist = self.get_file_breaks(filename)
Guido van Rossum921c8241992-01-10 14:54:42 +0000234 try:
235 for lineno in range(first, last+1):
236 line = linecache.getline(filename, lineno)
237 if not line:
238 print '[EOF]'
239 break
240 else:
241 s = string.rjust(`lineno`, 3)
242 if len(s) < 4: s = s + ' '
243 if lineno in breaklist: s = s + 'B'
244 else: s = s + ' '
245 if lineno == self.curframe.f_lineno:
246 s = s + '->'
247 print s + '\t' + line,
248 self.lineno = lineno
249 except KeyboardInterrupt:
250 pass
251 do_l = do_list
Guido van Rossum00230781993-03-29 11:39:45 +0000252
253 def do_whatis(self, arg):
Guido van Rossum00230781993-03-29 11:39:45 +0000254 try:
255 value = eval(arg, self.curframe.f_globals, \
256 self.curframe.f_locals)
257 except:
258 print '***', sys.exc_type + ':', `sys.exc_value`
259 return
260 code = None
261 # Is it a function?
262 try: code = value.func_code
263 except: pass
264 if code:
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265 print 'Function', code.co_name
Guido van Rossum00230781993-03-29 11:39:45 +0000266 return
267 # Is it an instance method?
268 try: code = value.im_func.func_code
269 except: pass
270 if code:
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271 print 'Method', code.co_name
Guido van Rossum00230781993-03-29 11:39:45 +0000272 return
273 # None of the above...
274 print type(value)
Guido van Rossumb9142571992-01-12 23:32:55 +0000275
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000276 # Print a traceback starting at the top stack frame.
Guido van Rossum23efba41992-01-27 16:58:47 +0000277 # The most recently entered frame is printed last;
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000278 # this is different from dbx and gdb, but consistent with
279 # the Python interpreter's stack trace.
280 # It is also consistent with the up/down commands (which are
281 # compatible with dbx and gdb: up moves towards 'main()'
282 # and down moves towards the most recent stack frame).
Guido van Rossum921c8241992-01-10 14:54:42 +0000283
Guido van Rossum23efba41992-01-27 16:58:47 +0000284 def print_stack_trace(self):
285 try:
286 for frame_lineno in self.stack:
287 self.print_stack_entry(frame_lineno)
288 except KeyboardInterrupt:
289 pass
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000290
Guido van Rossuma558e371994-11-10 22:27:35 +0000291 def print_stack_entry(self, frame_lineno, prompt_prefix=''):
Guido van Rossum23efba41992-01-27 16:58:47 +0000292 frame, lineno = frame_lineno
293 if frame is self.curframe:
294 print '>',
295 else:
296 print ' ',
Guido van Rossuma558e371994-11-10 22:27:35 +0000297 print self.format_stack_entry(frame_lineno, prompt_prefix)
Guido van Rossum921c8241992-01-10 14:54:42 +0000298
299
Guido van Rossumb6775db1994-08-01 11:34:53 +0000300 # Help methods (derived from pdb.doc)
301
302 def help_help(self):
303 self.help_h()
304
305 def help_h(self):
306 print """h(elp)
307 Without argument, print the list of available commands.
308 With a command name as argument, print help about that command
309 "help pdb" pipes the full documentation file to the $PAGER
310 "help exec" gives help on the ! command"""
311
312 def help_where(self):
313 self.help_w()
314
315 def help_w(self):
316 print """w(here)
317 Print a stack trace, with the most recent frame at the bottom.
318 An arrow indicates the "current frame", which determines the
319 context of most commands."""
320
321 def help_down(self):
322 self.help_d()
323
324 def help_d(self):
325 print """d(own)
326 Move the current frame one level down in the stack trace
327 (to an older frame)."""
328
329 def help_up(self):
330 self.help_u()
331
332 def help_u(self):
333 print """u(p)
334 Move the current frame one level up in the stack trace
335 (to a newer frame)."""
336
337 def help_break(self):
338 self.help_b()
339
340 def help_b(self):
341 print """b(reak) [lineno | function]
342 With a line number argument, set a break there in the current
343 file. With a function name, set a break at the entry of that
344 function. Without argument, list all breaks."""
345
346 def help_clear(self):
347 self.help_cl()
348
349 def help_cl(self):
350 print """cl(ear) [lineno]
351 With a line number argument, clear that break in the current file.
352 Without argument, clear all breaks (but first ask confirmation)."""
353
354 def help_step(self):
355 self.help_s()
356
357 def help_s(self):
358 print """s(tep)
359 Execute the current line, stop at the first possible occasion
360 (either in a function that is called or in the current function)."""
361
362 def help_next(self):
363 self.help_n()
364
365 def help_n(self):
366 print """n(ext)
367 Continue execution until the next line in the current function
368 is reached or it returns."""
369
370 def help_return(self):
371 self.help_r()
372
373 def help_r(self):
374 print """r(eturn)
375 Continue execution until the current function returns."""
376
377 def help_continue(self):
378 self.help_c()
379
380 def help_cont(self):
381 self.help_c()
382
383 def help_c(self):
384 print """c(ont(inue))
385 Continue execution, only stop when a breakpoint is encountered."""
386
387 def help_list(self):
388 self.help_l()
389
390 def help_l(self):
391 print """l(ist) [first [,last]]
392 List source code for the current file.
393 Without arguments, list 11 lines around the current line
394 or continue the previous listing.
395 With one argument, list 11 lines starting at that line.
396 With two arguments, list the given range;
397 if the second argument is less than the first, it is a count."""
398
399 def help_args(self):
400 self.help_a()
401
402 def help_a(self):
403 print """a(rgs)
404 Print the argument list of the current function."""
405
406 def help_p(self):
407 print """p expression
408 Print the value of the expression."""
409
410 def help_exec(self):
411 print """(!) statement
412 Execute the (one-line) statement in the context of
413 the current stack frame.
414 The exclamation point can be omitted unless the first word
415 of the statement resembles a debugger command.
416 To assign to a global variable you must always prefix the
417 command with a 'global' command, e.g.:
418 (Pdb) global list_options; list_options = ['-l']
419 (Pdb)"""
420
421 def help_quit(self):
422 self.help_q()
423
424 def help_q(self):
425 print """q(uit) Quit from the debugger.
426 The program being executed is aborted."""
427
428 def help_pdb(self):
429 help()
430
Guido van Rossum35771131992-09-08 11:59:04 +0000431# Simplified interface
432
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000433def run(statement):
Guido van Rossum5ef74b81993-06-23 11:55:24 +0000434 Pdb().run(statement)
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000435
436def runctx(statement, globals, locals):
Guido van Rossum5ef74b81993-06-23 11:55:24 +0000437 Pdb().runctx(statement, globals, locals)
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000438
Guido van Rossum4e160981992-09-02 20:43:20 +0000439def runcall(*args):
Guido van Rossum5ef74b81993-06-23 11:55:24 +0000440 apply(Pdb().runcall, args)
Guido van Rossum4e160981992-09-02 20:43:20 +0000441
Guido van Rossumb6775db1994-08-01 11:34:53 +0000442def set_trace():
443 Pdb().set_trace()
Guido van Rossum35771131992-09-08 11:59:04 +0000444
445# Post-Mortem interface
446
447def post_mortem(t):
Guido van Rossum5ef74b81993-06-23 11:55:24 +0000448 p = Pdb()
Guido van Rossum35771131992-09-08 11:59:04 +0000449 p.reset()
450 while t.tb_next <> None: t = t.tb_next
451 p.interaction(t.tb_frame, t)
452
453def pm():
454 import sys
455 post_mortem(sys.last_traceback)
456
457
458# Main program for testing
459
Guido van Rossum23efba41992-01-27 16:58:47 +0000460TESTCMD = 'import x; x.main()'
Guido van Rossum6fe08b01992-01-16 13:50:21 +0000461
Guido van Rossum921c8241992-01-10 14:54:42 +0000462def test():
Guido van Rossum23efba41992-01-27 16:58:47 +0000463 run(TESTCMD)
Guido van Rossume61fa0a1993-10-22 13:56:35 +0000464
465# print help
466def help():
Guido van Rossumb37954f1993-10-22 13:57:38 +0000467 import os
Guido van Rossume61fa0a1993-10-22 13:56:35 +0000468 for dirname in sys.path:
469 fullname = os.path.join(dirname, 'pdb.doc')
470 if os.path.exists(fullname):
471 sts = os.system('${PAGER-more} '+fullname)
472 if sts: print '*** Pager exit status:', sts
473 break
474 else:
475 print 'Sorry, can\'t find the help file "pdb.doc"',
476 print 'along the Python search path'