|
1 #! /usr/bin/env python |
|
2 |
|
3 """A Python debugger.""" |
|
4 |
|
5 # (See pdb.doc for documentation.) |
|
6 |
|
7 import sys |
|
8 import linecache |
|
9 import cmd |
|
10 import bdb |
|
11 from repr import Repr |
|
12 import os |
|
13 import re |
|
14 import pprint |
|
15 import traceback |
|
16 |
|
17 |
|
18 class Restart(Exception): |
|
19 """Causes a debugger to be restarted for the debugged python program.""" |
|
20 pass |
|
21 |
|
22 # Create a custom safe Repr instance and increase its maxstring. |
|
23 # The default of 30 truncates error messages too easily. |
|
24 _repr = Repr() |
|
25 _repr.maxstring = 200 |
|
26 _saferepr = _repr.repr |
|
27 |
|
28 __all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace", |
|
29 "post_mortem", "help"] |
|
30 |
|
31 def find_function(funcname, filename): |
|
32 cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname)) |
|
33 try: |
|
34 fp = open(filename) |
|
35 except IOError: |
|
36 return None |
|
37 # consumer of this info expects the first line to be 1 |
|
38 lineno = 1 |
|
39 answer = None |
|
40 while 1: |
|
41 line = fp.readline() |
|
42 if line == '': |
|
43 break |
|
44 if cre.match(line): |
|
45 answer = funcname, filename, lineno |
|
46 break |
|
47 lineno = lineno + 1 |
|
48 fp.close() |
|
49 return answer |
|
50 |
|
51 |
|
52 # Interaction prompt line will separate file and call info from code |
|
53 # text using value of line_prefix string. A newline and arrow may |
|
54 # be to your liking. You can set it once pdb is imported using the |
|
55 # command "pdb.line_prefix = '\n% '". |
|
56 # line_prefix = ': ' # Use this to get the old situation back |
|
57 line_prefix = '\n-> ' # Probably a better default |
|
58 |
|
59 class Pdb(bdb.Bdb, cmd.Cmd): |
|
60 |
|
61 def __init__(self, completekey='tab', stdin=None, stdout=None): |
|
62 bdb.Bdb.__init__(self) |
|
63 cmd.Cmd.__init__(self, completekey, stdin, stdout) |
|
64 if stdout: |
|
65 self.use_rawinput = 0 |
|
66 self.prompt = '(Pdb) ' |
|
67 self.aliases = {} |
|
68 self.mainpyfile = '' |
|
69 self._wait_for_mainpyfile = 0 |
|
70 # Try to load readline if it exists |
|
71 try: |
|
72 import readline |
|
73 except ImportError: |
|
74 pass |
|
75 |
|
76 # Read $HOME/.pdbrc and ./.pdbrc |
|
77 self.rcLines = [] |
|
78 if 'HOME' in os.environ: |
|
79 envHome = os.environ['HOME'] |
|
80 try: |
|
81 rcFile = open(os.path.join(envHome, ".pdbrc")) |
|
82 except IOError: |
|
83 pass |
|
84 else: |
|
85 for line in rcFile.readlines(): |
|
86 self.rcLines.append(line) |
|
87 rcFile.close() |
|
88 try: |
|
89 rcFile = open(".pdbrc") |
|
90 except IOError: |
|
91 pass |
|
92 else: |
|
93 for line in rcFile.readlines(): |
|
94 self.rcLines.append(line) |
|
95 rcFile.close() |
|
96 |
|
97 self.commands = {} # associates a command list to breakpoint numbers |
|
98 self.commands_doprompt = {} # for each bp num, tells if the prompt must be disp. after execing the cmd list |
|
99 self.commands_silent = {} # for each bp num, tells if the stack trace must be disp. after execing the cmd list |
|
100 self.commands_defining = False # True while in the process of defining a command list |
|
101 self.commands_bnum = None # The breakpoint number for which we are defining a list |
|
102 |
|
103 def reset(self): |
|
104 bdb.Bdb.reset(self) |
|
105 self.forget() |
|
106 |
|
107 def forget(self): |
|
108 self.lineno = None |
|
109 self.stack = [] |
|
110 self.curindex = 0 |
|
111 self.curframe = None |
|
112 |
|
113 def setup(self, f, t): |
|
114 self.forget() |
|
115 self.stack, self.curindex = self.get_stack(f, t) |
|
116 self.curframe = self.stack[self.curindex][0] |
|
117 self.execRcLines() |
|
118 |
|
119 # Can be executed earlier than 'setup' if desired |
|
120 def execRcLines(self): |
|
121 if self.rcLines: |
|
122 # Make local copy because of recursion |
|
123 rcLines = self.rcLines |
|
124 # executed only once |
|
125 self.rcLines = [] |
|
126 for line in rcLines: |
|
127 line = line[:-1] |
|
128 if len(line) > 0 and line[0] != '#': |
|
129 self.onecmd(line) |
|
130 |
|
131 # Override Bdb methods |
|
132 |
|
133 def user_call(self, frame, argument_list): |
|
134 """This method is called when there is the remote possibility |
|
135 that we ever need to stop in this function.""" |
|
136 if self._wait_for_mainpyfile: |
|
137 return |
|
138 if self.stop_here(frame): |
|
139 print >>self.stdout, '--Call--' |
|
140 self.interaction(frame, None) |
|
141 |
|
142 def user_line(self, frame): |
|
143 """This function is called when we stop or break at this line.""" |
|
144 if self._wait_for_mainpyfile: |
|
145 if (self.mainpyfile != self.canonic(frame.f_code.co_filename) |
|
146 or frame.f_lineno<= 0): |
|
147 return |
|
148 self._wait_for_mainpyfile = 0 |
|
149 if self.bp_commands(frame): |
|
150 self.interaction(frame, None) |
|
151 |
|
152 def bp_commands(self,frame): |
|
153 """ Call every command that was set for the current active breakpoint (if there is one) |
|
154 Returns True if the normal interaction function must be called, False otherwise """ |
|
155 #self.currentbp is set in bdb.py in bdb.break_here if a breakpoint was hit |
|
156 if getattr(self,"currentbp",False) and self.currentbp in self.commands: |
|
157 currentbp = self.currentbp |
|
158 self.currentbp = 0 |
|
159 lastcmd_back = self.lastcmd |
|
160 self.setup(frame, None) |
|
161 for line in self.commands[currentbp]: |
|
162 self.onecmd(line) |
|
163 self.lastcmd = lastcmd_back |
|
164 if not self.commands_silent[currentbp]: |
|
165 self.print_stack_entry(self.stack[self.curindex]) |
|
166 if self.commands_doprompt[currentbp]: |
|
167 self.cmdloop() |
|
168 self.forget() |
|
169 return |
|
170 return 1 |
|
171 |
|
172 def user_return(self, frame, return_value): |
|
173 """This function is called when a return trap is set here.""" |
|
174 frame.f_locals['__return__'] = return_value |
|
175 print >>self.stdout, '--Return--' |
|
176 self.interaction(frame, None) |
|
177 |
|
178 def user_exception(self, frame, exc_info): |
|
179 exc_type, exc_value, exc_traceback = exc_info |
|
180 """This function is called if an exception occurs, |
|
181 but only if we are to stop at or just below this level.""" |
|
182 frame.f_locals['__exception__'] = exc_type, exc_value |
|
183 if type(exc_type) == type(''): |
|
184 exc_type_name = exc_type |
|
185 else: exc_type_name = exc_type.__name__ |
|
186 print >>self.stdout, exc_type_name + ':', _saferepr(exc_value) |
|
187 self.interaction(frame, exc_traceback) |
|
188 |
|
189 # General interaction function |
|
190 |
|
191 def interaction(self, frame, traceback): |
|
192 self.setup(frame, traceback) |
|
193 self.print_stack_entry(self.stack[self.curindex]) |
|
194 self.cmdloop() |
|
195 self.forget() |
|
196 |
|
197 def default(self, line): |
|
198 if line[:1] == '!': line = line[1:] |
|
199 locals = self.curframe.f_locals |
|
200 globals = self.curframe.f_globals |
|
201 try: |
|
202 code = compile(line + '\n', '<stdin>', 'single') |
|
203 save_stdout = sys.stdout |
|
204 save_stdin = sys.stdin |
|
205 try: |
|
206 sys.stdin = self.stdin |
|
207 sys.stdout = self.stdout |
|
208 exec code in globals, locals |
|
209 finally: |
|
210 sys.stdout = save_stdout |
|
211 sys.stdin = save_stdin |
|
212 except: |
|
213 t, v = sys.exc_info()[:2] |
|
214 if type(t) == type(''): |
|
215 exc_type_name = t |
|
216 else: exc_type_name = t.__name__ |
|
217 print >>self.stdout, '***', exc_type_name + ':', v |
|
218 |
|
219 def precmd(self, line): |
|
220 """Handle alias expansion and ';;' separator.""" |
|
221 if not line.strip(): |
|
222 return line |
|
223 args = line.split() |
|
224 while args[0] in self.aliases: |
|
225 line = self.aliases[args[0]] |
|
226 ii = 1 |
|
227 for tmpArg in args[1:]: |
|
228 line = line.replace("%" + str(ii), |
|
229 tmpArg) |
|
230 ii = ii + 1 |
|
231 line = line.replace("%*", ' '.join(args[1:])) |
|
232 args = line.split() |
|
233 # split into ';;' separated commands |
|
234 # unless it's an alias command |
|
235 if args[0] != 'alias': |
|
236 marker = line.find(';;') |
|
237 if marker >= 0: |
|
238 # queue up everything after marker |
|
239 next = line[marker+2:].lstrip() |
|
240 self.cmdqueue.append(next) |
|
241 line = line[:marker].rstrip() |
|
242 return line |
|
243 |
|
244 def onecmd(self, line): |
|
245 """Interpret the argument as though it had been typed in response |
|
246 to the prompt. |
|
247 |
|
248 Checks whether this line is typed at the normal prompt or in |
|
249 a breakpoint command list definition. |
|
250 """ |
|
251 if not self.commands_defining: |
|
252 return cmd.Cmd.onecmd(self, line) |
|
253 else: |
|
254 return self.handle_command_def(line) |
|
255 |
|
256 def handle_command_def(self,line): |
|
257 """ Handles one command line during command list definition. """ |
|
258 cmd, arg, line = self.parseline(line) |
|
259 if cmd == 'silent': |
|
260 self.commands_silent[self.commands_bnum] = True |
|
261 return # continue to handle other cmd def in the cmd list |
|
262 elif cmd == 'end': |
|
263 self.cmdqueue = [] |
|
264 return 1 # end of cmd list |
|
265 cmdlist = self.commands[self.commands_bnum] |
|
266 if (arg): |
|
267 cmdlist.append(cmd+' '+arg) |
|
268 else: |
|
269 cmdlist.append(cmd) |
|
270 # Determine if we must stop |
|
271 try: |
|
272 func = getattr(self, 'do_' + cmd) |
|
273 except AttributeError: |
|
274 func = self.default |
|
275 if func.func_name in self.commands_resuming : # one of the resuming commands. |
|
276 self.commands_doprompt[self.commands_bnum] = False |
|
277 self.cmdqueue = [] |
|
278 return 1 |
|
279 return |
|
280 |
|
281 # Command definitions, called by cmdloop() |
|
282 # The argument is the remaining string on the command line |
|
283 # Return true to exit from the command loop |
|
284 |
|
285 do_h = cmd.Cmd.do_help |
|
286 |
|
287 def do_commands(self, arg): |
|
288 """Defines a list of commands associated to a breakpoint |
|
289 Those commands will be executed whenever the breakpoint causes the program to stop execution.""" |
|
290 if not arg: |
|
291 bnum = len(bdb.Breakpoint.bpbynumber)-1 |
|
292 else: |
|
293 try: |
|
294 bnum = int(arg) |
|
295 except: |
|
296 print >>self.stdout, "Usage : commands [bnum]\n ...\n end" |
|
297 return |
|
298 self.commands_bnum = bnum |
|
299 self.commands[bnum] = [] |
|
300 self.commands_doprompt[bnum] = True |
|
301 self.commands_silent[bnum] = False |
|
302 prompt_back = self.prompt |
|
303 self.prompt = '(com) ' |
|
304 self.commands_defining = True |
|
305 self.cmdloop() |
|
306 self.commands_defining = False |
|
307 self.prompt = prompt_back |
|
308 |
|
309 def do_break(self, arg, temporary = 0): |
|
310 # break [ ([filename:]lineno | function) [, "condition"] ] |
|
311 if not arg: |
|
312 if self.breaks: # There's at least one |
|
313 print >>self.stdout, "Num Type Disp Enb Where" |
|
314 for bp in bdb.Breakpoint.bpbynumber: |
|
315 if bp: |
|
316 bp.bpprint(self.stdout) |
|
317 return |
|
318 # parse arguments; comma has lowest precedence |
|
319 # and cannot occur in filename |
|
320 filename = None |
|
321 lineno = None |
|
322 cond = None |
|
323 comma = arg.find(',') |
|
324 if comma > 0: |
|
325 # parse stuff after comma: "condition" |
|
326 cond = arg[comma+1:].lstrip() |
|
327 arg = arg[:comma].rstrip() |
|
328 # parse stuff before comma: [filename:]lineno | function |
|
329 colon = arg.rfind(':') |
|
330 funcname = None |
|
331 if colon >= 0: |
|
332 filename = arg[:colon].rstrip() |
|
333 f = self.lookupmodule(filename) |
|
334 if not f: |
|
335 print >>self.stdout, '*** ', repr(filename), |
|
336 print >>self.stdout, 'not found from sys.path' |
|
337 return |
|
338 else: |
|
339 filename = f |
|
340 arg = arg[colon+1:].lstrip() |
|
341 try: |
|
342 lineno = int(arg) |
|
343 except ValueError, msg: |
|
344 print >>self.stdout, '*** Bad lineno:', arg |
|
345 return |
|
346 else: |
|
347 # no colon; can be lineno or function |
|
348 try: |
|
349 lineno = int(arg) |
|
350 except ValueError: |
|
351 try: |
|
352 func = eval(arg, |
|
353 self.curframe.f_globals, |
|
354 self.curframe.f_locals) |
|
355 except: |
|
356 func = arg |
|
357 try: |
|
358 if hasattr(func, 'im_func'): |
|
359 func = func.im_func |
|
360 code = func.func_code |
|
361 #use co_name to identify the bkpt (function names |
|
362 #could be aliased, but co_name is invariant) |
|
363 funcname = code.co_name |
|
364 lineno = code.co_firstlineno |
|
365 filename = code.co_filename |
|
366 except: |
|
367 # last thing to try |
|
368 (ok, filename, ln) = self.lineinfo(arg) |
|
369 if not ok: |
|
370 print >>self.stdout, '*** The specified object', |
|
371 print >>self.stdout, repr(arg), |
|
372 print >>self.stdout, 'is not a function' |
|
373 print >>self.stdout, 'or was not found along sys.path.' |
|
374 return |
|
375 funcname = ok # ok contains a function name |
|
376 lineno = int(ln) |
|
377 if not filename: |
|
378 filename = self.defaultFile() |
|
379 # Check for reasonable breakpoint |
|
380 line = self.checkline(filename, lineno) |
|
381 if line: |
|
382 # now set the break point |
|
383 err = self.set_break(filename, line, temporary, cond, funcname) |
|
384 if err: print >>self.stdout, '***', err |
|
385 else: |
|
386 bp = self.get_breaks(filename, line)[-1] |
|
387 print >>self.stdout, "Breakpoint %d at %s:%d" % (bp.number, |
|
388 bp.file, |
|
389 bp.line) |
|
390 |
|
391 # To be overridden in derived debuggers |
|
392 def defaultFile(self): |
|
393 """Produce a reasonable default.""" |
|
394 filename = self.curframe.f_code.co_filename |
|
395 if filename == '<string>' and self.mainpyfile: |
|
396 filename = self.mainpyfile |
|
397 return filename |
|
398 |
|
399 do_b = do_break |
|
400 |
|
401 def do_tbreak(self, arg): |
|
402 self.do_break(arg, 1) |
|
403 |
|
404 def lineinfo(self, identifier): |
|
405 failed = (None, None, None) |
|
406 # Input is identifier, may be in single quotes |
|
407 idstring = identifier.split("'") |
|
408 if len(idstring) == 1: |
|
409 # not in single quotes |
|
410 id = idstring[0].strip() |
|
411 elif len(idstring) == 3: |
|
412 # quoted |
|
413 id = idstring[1].strip() |
|
414 else: |
|
415 return failed |
|
416 if id == '': return failed |
|
417 parts = id.split('.') |
|
418 # Protection for derived debuggers |
|
419 if parts[0] == 'self': |
|
420 del parts[0] |
|
421 if len(parts) == 0: |
|
422 return failed |
|
423 # Best first guess at file to look at |
|
424 fname = self.defaultFile() |
|
425 if len(parts) == 1: |
|
426 item = parts[0] |
|
427 else: |
|
428 # More than one part. |
|
429 # First is module, second is method/class |
|
430 f = self.lookupmodule(parts[0]) |
|
431 if f: |
|
432 fname = f |
|
433 item = parts[1] |
|
434 answer = find_function(item, fname) |
|
435 return answer or failed |
|
436 |
|
437 def checkline(self, filename, lineno): |
|
438 """Check whether specified line seems to be executable. |
|
439 |
|
440 Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank |
|
441 line or EOF). Warning: testing is not comprehensive. |
|
442 """ |
|
443 line = linecache.getline(filename, lineno) |
|
444 if not line: |
|
445 print >>self.stdout, 'End of file' |
|
446 return 0 |
|
447 line = line.strip() |
|
448 # Don't allow setting breakpoint at a blank line |
|
449 if (not line or (line[0] == '#') or |
|
450 (line[:3] == '"""') or line[:3] == "'''"): |
|
451 print >>self.stdout, '*** Blank or comment' |
|
452 return 0 |
|
453 return lineno |
|
454 |
|
455 def do_enable(self, arg): |
|
456 args = arg.split() |
|
457 for i in args: |
|
458 try: |
|
459 i = int(i) |
|
460 except ValueError: |
|
461 print >>self.stdout, 'Breakpoint index %r is not a number' % i |
|
462 continue |
|
463 |
|
464 if not (0 <= i < len(bdb.Breakpoint.bpbynumber)): |
|
465 print >>self.stdout, 'No breakpoint numbered', i |
|
466 continue |
|
467 |
|
468 bp = bdb.Breakpoint.bpbynumber[i] |
|
469 if bp: |
|
470 bp.enable() |
|
471 |
|
472 def do_disable(self, arg): |
|
473 args = arg.split() |
|
474 for i in args: |
|
475 try: |
|
476 i = int(i) |
|
477 except ValueError: |
|
478 print >>self.stdout, 'Breakpoint index %r is not a number' % i |
|
479 continue |
|
480 |
|
481 if not (0 <= i < len(bdb.Breakpoint.bpbynumber)): |
|
482 print >>self.stdout, 'No breakpoint numbered', i |
|
483 continue |
|
484 |
|
485 bp = bdb.Breakpoint.bpbynumber[i] |
|
486 if bp: |
|
487 bp.disable() |
|
488 |
|
489 def do_condition(self, arg): |
|
490 # arg is breakpoint number and condition |
|
491 args = arg.split(' ', 1) |
|
492 try: |
|
493 bpnum = int(args[0].strip()) |
|
494 except ValueError: |
|
495 # something went wrong |
|
496 print >>self.stdout, \ |
|
497 'Breakpoint index %r is not a number' % args[0] |
|
498 return |
|
499 try: |
|
500 cond = args[1] |
|
501 except: |
|
502 cond = None |
|
503 try: |
|
504 bp = bdb.Breakpoint.bpbynumber[bpnum] |
|
505 except IndexError: |
|
506 print >>self.stdout, 'Breakpoint index %r is not valid' % args[0] |
|
507 return |
|
508 if bp: |
|
509 bp.cond = cond |
|
510 if not cond: |
|
511 print >>self.stdout, 'Breakpoint', bpnum, |
|
512 print >>self.stdout, 'is now unconditional.' |
|
513 |
|
514 def do_ignore(self,arg): |
|
515 """arg is bp number followed by ignore count.""" |
|
516 args = arg.split() |
|
517 try: |
|
518 bpnum = int(args[0].strip()) |
|
519 except ValueError: |
|
520 # something went wrong |
|
521 print >>self.stdout, \ |
|
522 'Breakpoint index %r is not a number' % args[0] |
|
523 return |
|
524 try: |
|
525 count = int(args[1].strip()) |
|
526 except: |
|
527 count = 0 |
|
528 try: |
|
529 bp = bdb.Breakpoint.bpbynumber[bpnum] |
|
530 except IndexError: |
|
531 print >>self.stdout, 'Breakpoint index %r is not valid' % args[0] |
|
532 return |
|
533 if bp: |
|
534 bp.ignore = count |
|
535 if count > 0: |
|
536 reply = 'Will ignore next ' |
|
537 if count > 1: |
|
538 reply = reply + '%d crossings' % count |
|
539 else: |
|
540 reply = reply + '1 crossing' |
|
541 print >>self.stdout, reply + ' of breakpoint %d.' % bpnum |
|
542 else: |
|
543 print >>self.stdout, 'Will stop next time breakpoint', |
|
544 print >>self.stdout, bpnum, 'is reached.' |
|
545 |
|
546 def do_clear(self, arg): |
|
547 """Three possibilities, tried in this order: |
|
548 clear -> clear all breaks, ask for confirmation |
|
549 clear file:lineno -> clear all breaks at file:lineno |
|
550 clear bpno bpno ... -> clear breakpoints by number""" |
|
551 if not arg: |
|
552 try: |
|
553 reply = raw_input('Clear all breaks? ') |
|
554 except EOFError: |
|
555 reply = 'no' |
|
556 reply = reply.strip().lower() |
|
557 if reply in ('y', 'yes'): |
|
558 self.clear_all_breaks() |
|
559 return |
|
560 if ':' in arg: |
|
561 # Make sure it works for "clear C:\foo\bar.py:12" |
|
562 i = arg.rfind(':') |
|
563 filename = arg[:i] |
|
564 arg = arg[i+1:] |
|
565 try: |
|
566 lineno = int(arg) |
|
567 except ValueError: |
|
568 err = "Invalid line number (%s)" % arg |
|
569 else: |
|
570 err = self.clear_break(filename, lineno) |
|
571 if err: print >>self.stdout, '***', err |
|
572 return |
|
573 numberlist = arg.split() |
|
574 for i in numberlist: |
|
575 try: |
|
576 i = int(i) |
|
577 except ValueError: |
|
578 print >>self.stdout, 'Breakpoint index %r is not a number' % i |
|
579 continue |
|
580 |
|
581 if not (0 <= i < len(bdb.Breakpoint.bpbynumber)): |
|
582 print >>self.stdout, 'No breakpoint numbered', i |
|
583 continue |
|
584 err = self.clear_bpbynumber(i) |
|
585 if err: |
|
586 print >>self.stdout, '***', err |
|
587 else: |
|
588 print >>self.stdout, 'Deleted breakpoint', i |
|
589 do_cl = do_clear # 'c' is already an abbreviation for 'continue' |
|
590 |
|
591 def do_where(self, arg): |
|
592 self.print_stack_trace() |
|
593 do_w = do_where |
|
594 do_bt = do_where |
|
595 |
|
596 def do_up(self, arg): |
|
597 if self.curindex == 0: |
|
598 print >>self.stdout, '*** Oldest frame' |
|
599 else: |
|
600 self.curindex = self.curindex - 1 |
|
601 self.curframe = self.stack[self.curindex][0] |
|
602 self.print_stack_entry(self.stack[self.curindex]) |
|
603 self.lineno = None |
|
604 do_u = do_up |
|
605 |
|
606 def do_down(self, arg): |
|
607 if self.curindex + 1 == len(self.stack): |
|
608 print >>self.stdout, '*** Newest frame' |
|
609 else: |
|
610 self.curindex = self.curindex + 1 |
|
611 self.curframe = self.stack[self.curindex][0] |
|
612 self.print_stack_entry(self.stack[self.curindex]) |
|
613 self.lineno = None |
|
614 do_d = do_down |
|
615 |
|
616 def do_until(self, arg): |
|
617 self.set_until(self.curframe) |
|
618 return 1 |
|
619 do_unt = do_until |
|
620 |
|
621 def do_step(self, arg): |
|
622 self.set_step() |
|
623 return 1 |
|
624 do_s = do_step |
|
625 |
|
626 def do_next(self, arg): |
|
627 self.set_next(self.curframe) |
|
628 return 1 |
|
629 do_n = do_next |
|
630 |
|
631 def do_run(self, arg): |
|
632 """Restart program by raising an exception to be caught in the main debugger |
|
633 loop. If arguments were given, set them in sys.argv.""" |
|
634 if arg: |
|
635 import shlex |
|
636 argv0 = sys.argv[0:1] |
|
637 sys.argv = shlex.split(arg) |
|
638 sys.argv[:0] = argv0 |
|
639 raise Restart |
|
640 |
|
641 do_restart = do_run |
|
642 |
|
643 def do_return(self, arg): |
|
644 self.set_return(self.curframe) |
|
645 return 1 |
|
646 do_r = do_return |
|
647 |
|
648 def do_continue(self, arg): |
|
649 self.set_continue() |
|
650 return 1 |
|
651 do_c = do_cont = do_continue |
|
652 |
|
653 def do_jump(self, arg): |
|
654 if self.curindex + 1 != len(self.stack): |
|
655 print >>self.stdout, "*** You can only jump within the bottom frame" |
|
656 return |
|
657 try: |
|
658 arg = int(arg) |
|
659 except ValueError: |
|
660 print >>self.stdout, "*** The 'jump' command requires a line number." |
|
661 else: |
|
662 try: |
|
663 # Do the jump, fix up our copy of the stack, and display the |
|
664 # new position |
|
665 self.curframe.f_lineno = arg |
|
666 self.stack[self.curindex] = self.stack[self.curindex][0], arg |
|
667 self.print_stack_entry(self.stack[self.curindex]) |
|
668 except ValueError, e: |
|
669 print >>self.stdout, '*** Jump failed:', e |
|
670 do_j = do_jump |
|
671 |
|
672 def do_debug(self, arg): |
|
673 sys.settrace(None) |
|
674 globals = self.curframe.f_globals |
|
675 locals = self.curframe.f_locals |
|
676 p = Pdb(self.completekey, self.stdin, self.stdout) |
|
677 p.prompt = "(%s) " % self.prompt.strip() |
|
678 print >>self.stdout, "ENTERING RECURSIVE DEBUGGER" |
|
679 sys.call_tracing(p.run, (arg, globals, locals)) |
|
680 print >>self.stdout, "LEAVING RECURSIVE DEBUGGER" |
|
681 sys.settrace(self.trace_dispatch) |
|
682 self.lastcmd = p.lastcmd |
|
683 |
|
684 def do_quit(self, arg): |
|
685 self._user_requested_quit = 1 |
|
686 self.set_quit() |
|
687 return 1 |
|
688 |
|
689 do_q = do_quit |
|
690 do_exit = do_quit |
|
691 |
|
692 def do_EOF(self, arg): |
|
693 print >>self.stdout |
|
694 self._user_requested_quit = 1 |
|
695 self.set_quit() |
|
696 return 1 |
|
697 |
|
698 def do_args(self, arg): |
|
699 f = self.curframe |
|
700 co = f.f_code |
|
701 dict = f.f_locals |
|
702 n = co.co_argcount |
|
703 if co.co_flags & 4: n = n+1 |
|
704 if co.co_flags & 8: n = n+1 |
|
705 for i in range(n): |
|
706 name = co.co_varnames[i] |
|
707 print >>self.stdout, name, '=', |
|
708 if name in dict: print >>self.stdout, dict[name] |
|
709 else: print >>self.stdout, "*** undefined ***" |
|
710 do_a = do_args |
|
711 |
|
712 def do_retval(self, arg): |
|
713 if '__return__' in self.curframe.f_locals: |
|
714 print >>self.stdout, self.curframe.f_locals['__return__'] |
|
715 else: |
|
716 print >>self.stdout, '*** Not yet returned!' |
|
717 do_rv = do_retval |
|
718 |
|
719 def _getval(self, arg): |
|
720 try: |
|
721 return eval(arg, self.curframe.f_globals, |
|
722 self.curframe.f_locals) |
|
723 except: |
|
724 t, v = sys.exc_info()[:2] |
|
725 if isinstance(t, str): |
|
726 exc_type_name = t |
|
727 else: exc_type_name = t.__name__ |
|
728 print >>self.stdout, '***', exc_type_name + ':', repr(v) |
|
729 raise |
|
730 |
|
731 def do_p(self, arg): |
|
732 try: |
|
733 print >>self.stdout, repr(self._getval(arg)) |
|
734 except: |
|
735 pass |
|
736 |
|
737 def do_pp(self, arg): |
|
738 try: |
|
739 pprint.pprint(self._getval(arg), self.stdout) |
|
740 except: |
|
741 pass |
|
742 |
|
743 def do_list(self, arg): |
|
744 self.lastcmd = 'list' |
|
745 last = None |
|
746 if arg: |
|
747 try: |
|
748 x = eval(arg, {}, {}) |
|
749 if type(x) == type(()): |
|
750 first, last = x |
|
751 first = int(first) |
|
752 last = int(last) |
|
753 if last < first: |
|
754 # Assume it's a count |
|
755 last = first + last |
|
756 else: |
|
757 first = max(1, int(x) - 5) |
|
758 except: |
|
759 print >>self.stdout, '*** Error in argument:', repr(arg) |
|
760 return |
|
761 elif self.lineno is None: |
|
762 first = max(1, self.curframe.f_lineno - 5) |
|
763 else: |
|
764 first = self.lineno + 1 |
|
765 if last is None: |
|
766 last = first + 10 |
|
767 filename = self.curframe.f_code.co_filename |
|
768 breaklist = self.get_file_breaks(filename) |
|
769 try: |
|
770 for lineno in range(first, last+1): |
|
771 line = linecache.getline(filename, lineno) |
|
772 if not line: |
|
773 print >>self.stdout, '[EOF]' |
|
774 break |
|
775 else: |
|
776 s = repr(lineno).rjust(3) |
|
777 if len(s) < 4: s = s + ' ' |
|
778 if lineno in breaklist: s = s + 'B' |
|
779 else: s = s + ' ' |
|
780 if lineno == self.curframe.f_lineno: |
|
781 s = s + '->' |
|
782 print >>self.stdout, s + '\t' + line, |
|
783 self.lineno = lineno |
|
784 except KeyboardInterrupt: |
|
785 pass |
|
786 do_l = do_list |
|
787 |
|
788 def do_whatis(self, arg): |
|
789 try: |
|
790 value = eval(arg, self.curframe.f_globals, |
|
791 self.curframe.f_locals) |
|
792 except: |
|
793 t, v = sys.exc_info()[:2] |
|
794 if type(t) == type(''): |
|
795 exc_type_name = t |
|
796 else: exc_type_name = t.__name__ |
|
797 print >>self.stdout, '***', exc_type_name + ':', repr(v) |
|
798 return |
|
799 code = None |
|
800 # Is it a function? |
|
801 try: code = value.func_code |
|
802 except: pass |
|
803 if code: |
|
804 print >>self.stdout, 'Function', code.co_name |
|
805 return |
|
806 # Is it an instance method? |
|
807 try: code = value.im_func.func_code |
|
808 except: pass |
|
809 if code: |
|
810 print >>self.stdout, 'Method', code.co_name |
|
811 return |
|
812 # None of the above... |
|
813 print >>self.stdout, type(value) |
|
814 |
|
815 def do_alias(self, arg): |
|
816 args = arg.split() |
|
817 if len(args) == 0: |
|
818 keys = self.aliases.keys() |
|
819 keys.sort() |
|
820 for alias in keys: |
|
821 print >>self.stdout, "%s = %s" % (alias, self.aliases[alias]) |
|
822 return |
|
823 if args[0] in self.aliases and len(args) == 1: |
|
824 print >>self.stdout, "%s = %s" % (args[0], self.aliases[args[0]]) |
|
825 else: |
|
826 self.aliases[args[0]] = ' '.join(args[1:]) |
|
827 |
|
828 def do_unalias(self, arg): |
|
829 args = arg.split() |
|
830 if len(args) == 0: return |
|
831 if args[0] in self.aliases: |
|
832 del self.aliases[args[0]] |
|
833 |
|
834 #list of all the commands making the program resume execution. |
|
835 commands_resuming = ['do_continue', 'do_step', 'do_next', 'do_return', |
|
836 'do_quit', 'do_jump'] |
|
837 |
|
838 # Print a traceback starting at the top stack frame. |
|
839 # The most recently entered frame is printed last; |
|
840 # this is different from dbx and gdb, but consistent with |
|
841 # the Python interpreter's stack trace. |
|
842 # It is also consistent with the up/down commands (which are |
|
843 # compatible with dbx and gdb: up moves towards 'main()' |
|
844 # and down moves towards the most recent stack frame). |
|
845 |
|
846 def print_stack_trace(self): |
|
847 try: |
|
848 for frame_lineno in self.stack: |
|
849 self.print_stack_entry(frame_lineno) |
|
850 except KeyboardInterrupt: |
|
851 pass |
|
852 |
|
853 def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix): |
|
854 frame, lineno = frame_lineno |
|
855 if frame is self.curframe: |
|
856 print >>self.stdout, '>', |
|
857 else: |
|
858 print >>self.stdout, ' ', |
|
859 print >>self.stdout, self.format_stack_entry(frame_lineno, |
|
860 prompt_prefix) |
|
861 |
|
862 |
|
863 # Help methods (derived from pdb.doc) |
|
864 |
|
865 def help_help(self): |
|
866 self.help_h() |
|
867 |
|
868 def help_h(self): |
|
869 print >>self.stdout, """h(elp) |
|
870 Without argument, print the list of available commands. |
|
871 With a command name as argument, print help about that command |
|
872 "help pdb" pipes the full documentation file to the $PAGER |
|
873 "help exec" gives help on the ! command""" |
|
874 |
|
875 def help_where(self): |
|
876 self.help_w() |
|
877 |
|
878 def help_w(self): |
|
879 print >>self.stdout, """w(here) |
|
880 Print a stack trace, with the most recent frame at the bottom. |
|
881 An arrow indicates the "current frame", which determines the |
|
882 context of most commands. 'bt' is an alias for this command.""" |
|
883 |
|
884 help_bt = help_w |
|
885 |
|
886 def help_down(self): |
|
887 self.help_d() |
|
888 |
|
889 def help_d(self): |
|
890 print >>self.stdout, """d(own) |
|
891 Move the current frame one level down in the stack trace |
|
892 (to a newer frame).""" |
|
893 |
|
894 def help_up(self): |
|
895 self.help_u() |
|
896 |
|
897 def help_u(self): |
|
898 print >>self.stdout, """u(p) |
|
899 Move the current frame one level up in the stack trace |
|
900 (to an older frame).""" |
|
901 |
|
902 def help_break(self): |
|
903 self.help_b() |
|
904 |
|
905 def help_b(self): |
|
906 print >>self.stdout, """b(reak) ([file:]lineno | function) [, condition] |
|
907 With a line number argument, set a break there in the current |
|
908 file. With a function name, set a break at first executable line |
|
909 of that function. Without argument, list all breaks. If a second |
|
910 argument is present, it is a string specifying an expression |
|
911 which must evaluate to true before the breakpoint is honored. |
|
912 |
|
913 The line number may be prefixed with a filename and a colon, |
|
914 to specify a breakpoint in another file (probably one that |
|
915 hasn't been loaded yet). The file is searched for on sys.path; |
|
916 the .py suffix may be omitted.""" |
|
917 |
|
918 def help_clear(self): |
|
919 self.help_cl() |
|
920 |
|
921 def help_cl(self): |
|
922 print >>self.stdout, "cl(ear) filename:lineno" |
|
923 print >>self.stdout, """cl(ear) [bpnumber [bpnumber...]] |
|
924 With a space separated list of breakpoint numbers, clear |
|
925 those breakpoints. Without argument, clear all breaks (but |
|
926 first ask confirmation). With a filename:lineno argument, |
|
927 clear all breaks at that line in that file. |
|
928 |
|
929 Note that the argument is different from previous versions of |
|
930 the debugger (in python distributions 1.5.1 and before) where |
|
931 a linenumber was used instead of either filename:lineno or |
|
932 breakpoint numbers.""" |
|
933 |
|
934 def help_tbreak(self): |
|
935 print >>self.stdout, """tbreak same arguments as break, but breakpoint is |
|
936 removed when first hit.""" |
|
937 |
|
938 def help_enable(self): |
|
939 print >>self.stdout, """enable bpnumber [bpnumber ...] |
|
940 Enables the breakpoints given as a space separated list of |
|
941 bp numbers.""" |
|
942 |
|
943 def help_disable(self): |
|
944 print >>self.stdout, """disable bpnumber [bpnumber ...] |
|
945 Disables the breakpoints given as a space separated list of |
|
946 bp numbers.""" |
|
947 |
|
948 def help_ignore(self): |
|
949 print >>self.stdout, """ignore bpnumber count |
|
950 Sets the ignore count for the given breakpoint number. A breakpoint |
|
951 becomes active when the ignore count is zero. When non-zero, the |
|
952 count is decremented each time the breakpoint is reached and the |
|
953 breakpoint is not disabled and any associated condition evaluates |
|
954 to true.""" |
|
955 |
|
956 def help_condition(self): |
|
957 print >>self.stdout, """condition bpnumber str_condition |
|
958 str_condition is a string specifying an expression which |
|
959 must evaluate to true before the breakpoint is honored. |
|
960 If str_condition is absent, any existing condition is removed; |
|
961 i.e., the breakpoint is made unconditional.""" |
|
962 |
|
963 def help_step(self): |
|
964 self.help_s() |
|
965 |
|
966 def help_s(self): |
|
967 print >>self.stdout, """s(tep) |
|
968 Execute the current line, stop at the first possible occasion |
|
969 (either in a function that is called or in the current function).""" |
|
970 |
|
971 def help_until(self): |
|
972 self.help_unt() |
|
973 |
|
974 def help_unt(self): |
|
975 print """unt(il) |
|
976 Continue execution until the line with a number greater than the current |
|
977 one is reached or until the current frame returns""" |
|
978 |
|
979 def help_next(self): |
|
980 self.help_n() |
|
981 |
|
982 def help_n(self): |
|
983 print >>self.stdout, """n(ext) |
|
984 Continue execution until the next line in the current function |
|
985 is reached or it returns.""" |
|
986 |
|
987 def help_return(self): |
|
988 self.help_r() |
|
989 |
|
990 def help_r(self): |
|
991 print >>self.stdout, """r(eturn) |
|
992 Continue execution until the current function returns.""" |
|
993 |
|
994 def help_continue(self): |
|
995 self.help_c() |
|
996 |
|
997 def help_cont(self): |
|
998 self.help_c() |
|
999 |
|
1000 def help_c(self): |
|
1001 print >>self.stdout, """c(ont(inue)) |
|
1002 Continue execution, only stop when a breakpoint is encountered.""" |
|
1003 |
|
1004 def help_jump(self): |
|
1005 self.help_j() |
|
1006 |
|
1007 def help_j(self): |
|
1008 print >>self.stdout, """j(ump) lineno |
|
1009 Set the next line that will be executed.""" |
|
1010 |
|
1011 def help_debug(self): |
|
1012 print >>self.stdout, """debug code |
|
1013 Enter a recursive debugger that steps through the code argument |
|
1014 (which is an arbitrary expression or statement to be executed |
|
1015 in the current environment).""" |
|
1016 |
|
1017 def help_list(self): |
|
1018 self.help_l() |
|
1019 |
|
1020 def help_l(self): |
|
1021 print >>self.stdout, """l(ist) [first [,last]] |
|
1022 List source code for the current file. |
|
1023 Without arguments, list 11 lines around the current line |
|
1024 or continue the previous listing. |
|
1025 With one argument, list 11 lines starting at that line. |
|
1026 With two arguments, list the given range; |
|
1027 if the second argument is less than the first, it is a count.""" |
|
1028 |
|
1029 def help_args(self): |
|
1030 self.help_a() |
|
1031 |
|
1032 def help_a(self): |
|
1033 print >>self.stdout, """a(rgs) |
|
1034 Print the arguments of the current function.""" |
|
1035 |
|
1036 def help_p(self): |
|
1037 print >>self.stdout, """p expression |
|
1038 Print the value of the expression.""" |
|
1039 |
|
1040 def help_pp(self): |
|
1041 print >>self.stdout, """pp expression |
|
1042 Pretty-print the value of the expression.""" |
|
1043 |
|
1044 def help_exec(self): |
|
1045 print >>self.stdout, """(!) statement |
|
1046 Execute the (one-line) statement in the context of |
|
1047 the current stack frame. |
|
1048 The exclamation point can be omitted unless the first word |
|
1049 of the statement resembles a debugger command. |
|
1050 To assign to a global variable you must always prefix the |
|
1051 command with a 'global' command, e.g.: |
|
1052 (Pdb) global list_options; list_options = ['-l'] |
|
1053 (Pdb)""" |
|
1054 |
|
1055 def help_run(self): |
|
1056 print """run [args...] |
|
1057 Restart the debugged python program. If a string is supplied, it is |
|
1058 splitted with "shlex" and the result is used as the new sys.argv. |
|
1059 History, breakpoints, actions and debugger options are preserved. |
|
1060 "restart" is an alias for "run".""" |
|
1061 |
|
1062 help_restart = help_run |
|
1063 |
|
1064 def help_quit(self): |
|
1065 self.help_q() |
|
1066 |
|
1067 def help_q(self): |
|
1068 print >>self.stdout, """q(uit) or exit - Quit from the debugger. |
|
1069 The program being executed is aborted.""" |
|
1070 |
|
1071 help_exit = help_q |
|
1072 |
|
1073 def help_whatis(self): |
|
1074 print >>self.stdout, """whatis arg |
|
1075 Prints the type of the argument.""" |
|
1076 |
|
1077 def help_EOF(self): |
|
1078 print >>self.stdout, """EOF |
|
1079 Handles the receipt of EOF as a command.""" |
|
1080 |
|
1081 def help_alias(self): |
|
1082 print >>self.stdout, """alias [name [command [parameter parameter ...] ]] |
|
1083 Creates an alias called 'name' the executes 'command'. The command |
|
1084 must *not* be enclosed in quotes. Replaceable parameters are |
|
1085 indicated by %1, %2, and so on, while %* is replaced by all the |
|
1086 parameters. If no command is given, the current alias for name |
|
1087 is shown. If no name is given, all aliases are listed. |
|
1088 |
|
1089 Aliases may be nested and can contain anything that can be |
|
1090 legally typed at the pdb prompt. Note! You *can* override |
|
1091 internal pdb commands with aliases! Those internal commands |
|
1092 are then hidden until the alias is removed. Aliasing is recursively |
|
1093 applied to the first word of the command line; all other words |
|
1094 in the line are left alone. |
|
1095 |
|
1096 Some useful aliases (especially when placed in the .pdbrc file) are: |
|
1097 |
|
1098 #Print instance variables (usage "pi classInst") |
|
1099 alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k] |
|
1100 |
|
1101 #Print instance variables in self |
|
1102 alias ps pi self |
|
1103 """ |
|
1104 |
|
1105 def help_unalias(self): |
|
1106 print >>self.stdout, """unalias name |
|
1107 Deletes the specified alias.""" |
|
1108 |
|
1109 def help_commands(self): |
|
1110 print >>self.stdout, """commands [bpnumber] |
|
1111 (com) ... |
|
1112 (com) end |
|
1113 (Pdb) |
|
1114 |
|
1115 Specify a list of commands for breakpoint number bpnumber. The |
|
1116 commands themselves appear on the following lines. Type a line |
|
1117 containing just 'end' to terminate the commands. |
|
1118 |
|
1119 To remove all commands from a breakpoint, type commands and |
|
1120 follow it immediately with end; that is, give no commands. |
|
1121 |
|
1122 With no bpnumber argument, commands refers to the last |
|
1123 breakpoint set. |
|
1124 |
|
1125 You can use breakpoint commands to start your program up again. |
|
1126 Simply use the continue command, or step, or any other |
|
1127 command that resumes execution. |
|
1128 |
|
1129 Specifying any command resuming execution (currently continue, |
|
1130 step, next, return, jump, quit and their abbreviations) terminates |
|
1131 the command list (as if that command was immediately followed by end). |
|
1132 This is because any time you resume execution |
|
1133 (even with a simple next or step), you may encounter |
|
1134 another breakpoint--which could have its own command list, leading to |
|
1135 ambiguities about which list to execute. |
|
1136 |
|
1137 If you use the 'silent' command in the command list, the |
|
1138 usual message about stopping at a breakpoint is not printed. This may |
|
1139 be desirable for breakpoints that are to print a specific message and |
|
1140 then continue. If none of the other commands print anything, you |
|
1141 see no sign that the breakpoint was reached. |
|
1142 """ |
|
1143 |
|
1144 def help_pdb(self): |
|
1145 help() |
|
1146 |
|
1147 def lookupmodule(self, filename): |
|
1148 """Helper function for break/clear parsing -- may be overridden. |
|
1149 |
|
1150 lookupmodule() translates (possibly incomplete) file or module name |
|
1151 into an absolute file name. |
|
1152 """ |
|
1153 if os.path.isabs(filename) and os.path.exists(filename): |
|
1154 return filename |
|
1155 f = os.path.join(sys.path[0], filename) |
|
1156 if os.path.exists(f) and self.canonic(f) == self.mainpyfile: |
|
1157 return f |
|
1158 root, ext = os.path.splitext(filename) |
|
1159 if ext == '': |
|
1160 filename = filename + '.py' |
|
1161 if os.path.isabs(filename): |
|
1162 return filename |
|
1163 for dirname in sys.path: |
|
1164 while os.path.islink(dirname): |
|
1165 dirname = os.readlink(dirname) |
|
1166 fullname = os.path.join(dirname, filename) |
|
1167 if os.path.exists(fullname): |
|
1168 return fullname |
|
1169 return None |
|
1170 |
|
1171 def _runscript(self, filename): |
|
1172 # The script has to run in __main__ namespace (or imports from |
|
1173 # __main__ will break). |
|
1174 # |
|
1175 # So we clear up the __main__ and set several special variables |
|
1176 # (this gets rid of pdb's globals and cleans old variables on restarts). |
|
1177 import __main__ |
|
1178 __main__.__dict__.clear() |
|
1179 __main__.__dict__.update({"__name__" : "__main__", |
|
1180 "__file__" : filename, |
|
1181 "__builtins__": __builtins__, |
|
1182 }) |
|
1183 |
|
1184 # When bdb sets tracing, a number of call and line events happens |
|
1185 # BEFORE debugger even reaches user's code (and the exact sequence of |
|
1186 # events depends on python version). So we take special measures to |
|
1187 # avoid stopping before we reach the main script (see user_line and |
|
1188 # user_call for details). |
|
1189 self._wait_for_mainpyfile = 1 |
|
1190 self.mainpyfile = self.canonic(filename) |
|
1191 self._user_requested_quit = 0 |
|
1192 statement = 'execfile( "%s")' % filename |
|
1193 self.run(statement) |
|
1194 |
|
1195 # Simplified interface |
|
1196 |
|
1197 def run(statement, globals=None, locals=None): |
|
1198 Pdb().run(statement, globals, locals) |
|
1199 |
|
1200 def runeval(expression, globals=None, locals=None): |
|
1201 return Pdb().runeval(expression, globals, locals) |
|
1202 |
|
1203 def runctx(statement, globals, locals): |
|
1204 # B/W compatibility |
|
1205 run(statement, globals, locals) |
|
1206 |
|
1207 def runcall(*args, **kwds): |
|
1208 return Pdb().runcall(*args, **kwds) |
|
1209 |
|
1210 def set_trace(): |
|
1211 Pdb().set_trace(sys._getframe().f_back) |
|
1212 |
|
1213 # Post-Mortem interface |
|
1214 |
|
1215 def post_mortem(t=None): |
|
1216 # handling the default |
|
1217 if t is None: |
|
1218 # sys.exc_info() returns (type, value, traceback) if an exception is |
|
1219 # being handled, otherwise it returns None |
|
1220 t = sys.exc_info()[2] |
|
1221 if t is None: |
|
1222 raise ValueError("A valid traceback must be passed if no " |
|
1223 "exception is being handled") |
|
1224 |
|
1225 p = Pdb() |
|
1226 p.reset() |
|
1227 p.interaction(None, t) |
|
1228 |
|
1229 def pm(): |
|
1230 post_mortem(sys.last_traceback) |
|
1231 |
|
1232 |
|
1233 # Main program for testing |
|
1234 |
|
1235 TESTCMD = 'import x; x.main()' |
|
1236 |
|
1237 def test(): |
|
1238 run(TESTCMD) |
|
1239 |
|
1240 # print help |
|
1241 def help(): |
|
1242 for dirname in sys.path: |
|
1243 fullname = os.path.join(dirname, 'pdb.doc') |
|
1244 if os.path.exists(fullname): |
|
1245 sts = os.system('${PAGER-more} '+fullname) |
|
1246 if sts: print '*** Pager exit status:', sts |
|
1247 break |
|
1248 else: |
|
1249 print 'Sorry, can\'t find the help file "pdb.doc"', |
|
1250 print 'along the Python search path' |
|
1251 |
|
1252 def main(): |
|
1253 if not sys.argv[1:] or sys.argv[1] in ("--help", "-h"): |
|
1254 print "usage: pdb.py scriptfile [arg] ..." |
|
1255 sys.exit(2) |
|
1256 |
|
1257 mainpyfile = sys.argv[1] # Get script filename |
|
1258 if not os.path.exists(mainpyfile): |
|
1259 print 'Error:', mainpyfile, 'does not exist' |
|
1260 sys.exit(1) |
|
1261 |
|
1262 del sys.argv[0] # Hide "pdb.py" from argument list |
|
1263 |
|
1264 # Replace pdb's dir with script's dir in front of module search path. |
|
1265 sys.path[0] = os.path.dirname(mainpyfile) |
|
1266 |
|
1267 # Note on saving/restoring sys.argv: it's a good idea when sys.argv was |
|
1268 # modified by the script being debugged. It's a bad idea when it was |
|
1269 # changed by the user from the command line. There is a "restart" command which |
|
1270 # allows explicit specification of command line arguments. |
|
1271 pdb = Pdb() |
|
1272 while 1: |
|
1273 try: |
|
1274 pdb._runscript(mainpyfile) |
|
1275 if pdb._user_requested_quit: |
|
1276 break |
|
1277 print "The program finished and will be restarted" |
|
1278 except Restart: |
|
1279 print "Restarting", mainpyfile, "with arguments:" |
|
1280 print "\t" + " ".join(sys.argv[1:]) |
|
1281 except SystemExit: |
|
1282 # In most cases SystemExit does not warrant a post-mortem session. |
|
1283 print "The program exited via sys.exit(). Exit status: ", |
|
1284 print sys.exc_info()[1] |
|
1285 except: |
|
1286 traceback.print_exc() |
|
1287 print "Uncaught exception. Entering post mortem debugging" |
|
1288 print "Running 'cont' or 'step' will restart the program" |
|
1289 t = sys.exc_info()[2] |
|
1290 pdb.interaction(None, t) |
|
1291 print "Post mortem debugger finished. The "+mainpyfile+" will be restarted" |
|
1292 |
|
1293 |
|
1294 # When invoked as main program, invoke the debugger on a script |
|
1295 if __name__ == '__main__': |
|
1296 import pdb |
|
1297 pdb.main() |