blob: 7ab50b4845d3e6ffae5b73133c0e1ef255affb69 [file] [log] [blame]
Haibo Huangd8830302020-03-03 10:09:46 -08001#! /usr/bin/env python3
2
3"""
4The Python Debugger Pdb
5=======================
6
7To use the debugger in its simplest form:
8
9 >>> import pdb
10 >>> pdb.run('<a statement>')
11
12The debugger's prompt is '(Pdb) '. This will stop in the first
13function call in <a statement>.
14
15Alternatively, if a statement terminated with an unhandled exception,
16you can use pdb's post-mortem facility to inspect the contents of the
17traceback:
18
19 >>> <a statement>
20 <exception traceback>
21 >>> import pdb
22 >>> pdb.pm()
23
24The commands recognized by the debugger are listed in the next
25section. Most can be abbreviated as indicated; e.g., h(elp) means
26that 'help' can be typed as 'h' or 'help' (but not as 'he' or 'hel',
27nor as 'H' or 'Help' or 'HELP'). Optional arguments are enclosed in
28square brackets. Alternatives in the command syntax are separated
29by a vertical bar (|).
30
31A blank line repeats the previous command literally, except for
32'list', where it lists the next 11 lines.
33
34Commands that the debugger doesn't recognize are assumed to be Python
35statements and are executed in the context of the program being
36debugged. Python statements can also be prefixed with an exclamation
37point ('!'). This is a powerful way to inspect the program being
38debugged; it is even possible to change variables or call functions.
39When an exception occurs in such a statement, the exception name is
40printed but the debugger's state is not changed.
41
42The debugger supports aliases, which can save typing. And aliases can
43have parameters (see the alias help entry) which allows one a certain
44level of adaptability to the context under examination.
45
46Multiple commands may be entered on a single line, separated by the
47pair ';;'. No intelligence is applied to separating the commands; the
48input is split at the first ';;', even if it is in the middle of a
49quoted string.
50
51If a file ".pdbrc" exists in your home directory or in the current
52directory, it is read in and executed as if it had been typed at the
53debugger prompt. This is particularly useful for aliases. If both
54files exist, the one in the home directory is read first and aliases
55defined there can be overridden by the local file. This behavior can be
56disabled by passing the "readrc=False" argument to the Pdb constructor.
57
58Aside from aliases, the debugger is not directly programmable; but it
59is implemented as a class from which you can derive your own debugger
60class, which you can make as fancy as you like.
61
62
63Debugger commands
64=================
65
66"""
67# NOTE: the actual command documentation is collected from docstrings of the
68# commands and is appended to __doc__ after the class has been defined.
69
70import os
71import io
72import re
73import sys
74import cmd
75import bdb
76import dis
77import code
78import glob
79import pprint
80import signal
81import inspect
Haibo Huangf5f93a72020-10-19 15:43:42 -070082import tokenize
Haibo Huangd8830302020-03-03 10:09:46 -080083import traceback
84import linecache
85
86
87class Restart(Exception):
88 """Causes a debugger to be restarted for the debugged python program."""
89 pass
90
91__all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace",
92 "post_mortem", "help"]
93
94def find_function(funcname, filename):
95 cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname))
96 try:
Haibo Huangf5f93a72020-10-19 15:43:42 -070097 fp = tokenize.open(filename)
Haibo Huangd8830302020-03-03 10:09:46 -080098 except OSError:
99 return None
100 # consumer of this info expects the first line to be 1
101 with fp:
102 for lineno, line in enumerate(fp, start=1):
103 if cre.match(line):
104 return funcname, filename, lineno
105 return None
106
107def getsourcelines(obj):
108 lines, lineno = inspect.findsource(obj)
109 if inspect.isframe(obj) and obj.f_globals is obj.f_locals:
110 # must be a module frame: do not try to cut a block out of it
111 return lines, 1
112 elif inspect.ismodule(obj):
113 return lines, 1
114 return inspect.getblock(lines[lineno:]), lineno+1
115
116def lasti2lineno(code, lasti):
117 linestarts = list(dis.findlinestarts(code))
118 linestarts.reverse()
119 for i, lineno in linestarts:
120 if lasti >= i:
121 return lineno
122 return 0
123
124
125class _rstr(str):
126 """String that doesn't quote its repr."""
127 def __repr__(self):
128 return self
129
130
131# Interaction prompt line will separate file and call info from code
132# text using value of line_prefix string. A newline and arrow may
133# be to your liking. You can set it once pdb is imported using the
134# command "pdb.line_prefix = '\n% '".
135# line_prefix = ': ' # Use this to get the old situation back
136line_prefix = '\n-> ' # Probably a better default
137
138class Pdb(bdb.Bdb, cmd.Cmd):
139
140 _previous_sigint_handler = None
141
142 def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
143 nosigint=False, readrc=True):
144 bdb.Bdb.__init__(self, skip=skip)
145 cmd.Cmd.__init__(self, completekey, stdin, stdout)
146 sys.audit("pdb.Pdb")
147 if stdout:
148 self.use_rawinput = 0
149 self.prompt = '(Pdb) '
150 self.aliases = {}
151 self.displaying = {}
152 self.mainpyfile = ''
153 self._wait_for_mainpyfile = False
154 self.tb_lineno = {}
155 # Try to load readline if it exists
156 try:
157 import readline
158 # remove some common file name delimiters
159 readline.set_completer_delims(' \t\n`@#$%^&*()=+[{]}\\|;:\'",<>?')
160 except ImportError:
161 pass
162 self.allow_kbdint = False
163 self.nosigint = nosigint
164
165 # Read ~/.pdbrc and ./.pdbrc
166 self.rcLines = []
167 if readrc:
168 try:
169 with open(os.path.expanduser('~/.pdbrc')) as rcFile:
170 self.rcLines.extend(rcFile)
171 except OSError:
172 pass
173 try:
174 with open(".pdbrc") as rcFile:
175 self.rcLines.extend(rcFile)
176 except OSError:
177 pass
178
179 self.commands = {} # associates a command list to breakpoint numbers
180 self.commands_doprompt = {} # for each bp num, tells if the prompt
181 # must be disp. after execing the cmd list
182 self.commands_silent = {} # for each bp num, tells if the stack trace
183 # must be disp. after execing the cmd list
184 self.commands_defining = False # True while in the process of defining
185 # a command list
186 self.commands_bnum = None # The breakpoint number for which we are
187 # defining a list
188
189 def sigint_handler(self, signum, frame):
190 if self.allow_kbdint:
191 raise KeyboardInterrupt
192 self.message("\nProgram interrupted. (Use 'cont' to resume).")
193 self.set_step()
194 self.set_trace(frame)
195
196 def reset(self):
197 bdb.Bdb.reset(self)
198 self.forget()
199
200 def forget(self):
201 self.lineno = None
202 self.stack = []
203 self.curindex = 0
204 self.curframe = None
205 self.tb_lineno.clear()
206
207 def setup(self, f, tb):
208 self.forget()
209 self.stack, self.curindex = self.get_stack(f, tb)
210 while tb:
211 # when setting up post-mortem debugging with a traceback, save all
212 # the original line numbers to be displayed along the current line
213 # numbers (which can be different, e.g. due to finally clauses)
214 lineno = lasti2lineno(tb.tb_frame.f_code, tb.tb_lasti)
215 self.tb_lineno[tb.tb_frame] = lineno
216 tb = tb.tb_next
217 self.curframe = self.stack[self.curindex][0]
218 # The f_locals dictionary is updated from the actual frame
219 # locals whenever the .f_locals accessor is called, so we
220 # cache it here to ensure that modifications are not overwritten.
221 self.curframe_locals = self.curframe.f_locals
222 return self.execRcLines()
223
224 # Can be executed earlier than 'setup' if desired
225 def execRcLines(self):
226 if not self.rcLines:
227 return
228 # local copy because of recursion
229 rcLines = self.rcLines
230 rcLines.reverse()
231 # execute every line only once
232 self.rcLines = []
233 while rcLines:
234 line = rcLines.pop().strip()
235 if line and line[0] != '#':
236 if self.onecmd(line):
237 # if onecmd returns True, the command wants to exit
238 # from the interaction, save leftover rc lines
239 # to execute before next interaction
240 self.rcLines += reversed(rcLines)
241 return True
242
243 # Override Bdb methods
244
245 def user_call(self, frame, argument_list):
246 """This method is called when there is the remote possibility
247 that we ever need to stop in this function."""
248 if self._wait_for_mainpyfile:
249 return
250 if self.stop_here(frame):
251 self.message('--Call--')
252 self.interaction(frame, None)
253
254 def user_line(self, frame):
255 """This function is called when we stop or break at this line."""
256 if self._wait_for_mainpyfile:
257 if (self.mainpyfile != self.canonic(frame.f_code.co_filename)
258 or frame.f_lineno <= 0):
259 return
260 self._wait_for_mainpyfile = False
261 if self.bp_commands(frame):
262 self.interaction(frame, None)
263
264 def bp_commands(self, frame):
265 """Call every command that was set for the current active breakpoint
266 (if there is one).
267
268 Returns True if the normal interaction function must be called,
269 False otherwise."""
270 # self.currentbp is set in bdb in Bdb.break_here if a breakpoint was hit
271 if getattr(self, "currentbp", False) and \
272 self.currentbp in self.commands:
273 currentbp = self.currentbp
274 self.currentbp = 0
275 lastcmd_back = self.lastcmd
276 self.setup(frame, None)
277 for line in self.commands[currentbp]:
278 self.onecmd(line)
279 self.lastcmd = lastcmd_back
280 if not self.commands_silent[currentbp]:
281 self.print_stack_entry(self.stack[self.curindex])
282 if self.commands_doprompt[currentbp]:
283 self._cmdloop()
284 self.forget()
285 return
286 return 1
287
288 def user_return(self, frame, return_value):
289 """This function is called when a return trap is set here."""
290 if self._wait_for_mainpyfile:
291 return
292 frame.f_locals['__return__'] = return_value
293 self.message('--Return--')
294 self.interaction(frame, None)
295
296 def user_exception(self, frame, exc_info):
297 """This function is called if an exception occurs,
298 but only if we are to stop at or just below this level."""
299 if self._wait_for_mainpyfile:
300 return
301 exc_type, exc_value, exc_traceback = exc_info
302 frame.f_locals['__exception__'] = exc_type, exc_value
303
304 # An 'Internal StopIteration' exception is an exception debug event
305 # issued by the interpreter when handling a subgenerator run with
306 # 'yield from' or a generator controlled by a for loop. No exception has
307 # actually occurred in this case. The debugger uses this debug event to
308 # stop when the debuggee is returning from such generators.
309 prefix = 'Internal ' if (not exc_traceback
310 and exc_type is StopIteration) else ''
311 self.message('%s%s' % (prefix,
312 traceback.format_exception_only(exc_type, exc_value)[-1].strip()))
313 self.interaction(frame, exc_traceback)
314
315 # General interaction function
316 def _cmdloop(self):
317 while True:
318 try:
319 # keyboard interrupts allow for an easy way to cancel
320 # the current command, so allow them during interactive input
321 self.allow_kbdint = True
322 self.cmdloop()
323 self.allow_kbdint = False
324 break
325 except KeyboardInterrupt:
326 self.message('--KeyboardInterrupt--')
327
328 # Called before loop, handles display expressions
329 def preloop(self):
330 displaying = self.displaying.get(self.curframe)
331 if displaying:
332 for expr, oldvalue in displaying.items():
333 newvalue = self._getval_except(expr)
334 # check for identity first; this prevents custom __eq__ to
335 # be called at every loop, and also prevents instances whose
336 # fields are changed to be displayed
337 if newvalue is not oldvalue and newvalue != oldvalue:
338 displaying[expr] = newvalue
339 self.message('display %s: %r [old: %r]' %
340 (expr, newvalue, oldvalue))
341
342 def interaction(self, frame, traceback):
343 # Restore the previous signal handler at the Pdb prompt.
344 if Pdb._previous_sigint_handler:
345 try:
346 signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
347 except ValueError: # ValueError: signal only works in main thread
348 pass
349 else:
350 Pdb._previous_sigint_handler = None
351 if self.setup(frame, traceback):
352 # no interaction desired at this time (happens if .pdbrc contains
353 # a command like "continue")
354 self.forget()
355 return
356 self.print_stack_entry(self.stack[self.curindex])
357 self._cmdloop()
358 self.forget()
359
360 def displayhook(self, obj):
361 """Custom displayhook for the exec in default(), which prevents
362 assignment of the _ variable in the builtins.
363 """
364 # reproduce the behavior of the standard displayhook, not printing None
365 if obj is not None:
366 self.message(repr(obj))
367
368 def default(self, line):
369 if line[:1] == '!': line = line[1:]
370 locals = self.curframe_locals
371 globals = self.curframe.f_globals
372 try:
373 code = compile(line + '\n', '<stdin>', 'single')
374 save_stdout = sys.stdout
375 save_stdin = sys.stdin
376 save_displayhook = sys.displayhook
377 try:
378 sys.stdin = self.stdin
379 sys.stdout = self.stdout
380 sys.displayhook = self.displayhook
381 exec(code, globals, locals)
382 finally:
383 sys.stdout = save_stdout
384 sys.stdin = save_stdin
385 sys.displayhook = save_displayhook
386 except:
Yi Kong71199322022-08-30 15:53:45 +0800387 self._error_exc()
Haibo Huangd8830302020-03-03 10:09:46 -0800388
389 def precmd(self, line):
390 """Handle alias expansion and ';;' separator."""
391 if not line.strip():
392 return line
393 args = line.split()
394 while args[0] in self.aliases:
395 line = self.aliases[args[0]]
396 ii = 1
397 for tmpArg in args[1:]:
398 line = line.replace("%" + str(ii),
399 tmpArg)
400 ii += 1
401 line = line.replace("%*", ' '.join(args[1:]))
402 args = line.split()
403 # split into ';;' separated commands
404 # unless it's an alias command
405 if args[0] != 'alias':
406 marker = line.find(';;')
407 if marker >= 0:
408 # queue up everything after marker
409 next = line[marker+2:].lstrip()
410 self.cmdqueue.append(next)
411 line = line[:marker].rstrip()
412 return line
413
414 def onecmd(self, line):
415 """Interpret the argument as though it had been typed in response
416 to the prompt.
417
418 Checks whether this line is typed at the normal prompt or in
419 a breakpoint command list definition.
420 """
421 if not self.commands_defining:
422 return cmd.Cmd.onecmd(self, line)
423 else:
424 return self.handle_command_def(line)
425
426 def handle_command_def(self, line):
427 """Handles one command line during command list definition."""
428 cmd, arg, line = self.parseline(line)
429 if not cmd:
430 return
431 if cmd == 'silent':
432 self.commands_silent[self.commands_bnum] = True
433 return # continue to handle other cmd def in the cmd list
434 elif cmd == 'end':
435 self.cmdqueue = []
436 return 1 # end of cmd list
437 cmdlist = self.commands[self.commands_bnum]
438 if arg:
439 cmdlist.append(cmd+' '+arg)
440 else:
441 cmdlist.append(cmd)
442 # Determine if we must stop
443 try:
444 func = getattr(self, 'do_' + cmd)
445 except AttributeError:
446 func = self.default
447 # one of the resuming commands
448 if func.__name__ in self.commands_resuming:
449 self.commands_doprompt[self.commands_bnum] = False
450 self.cmdqueue = []
451 return 1
452 return
453
454 # interface abstraction functions
455
456 def message(self, msg):
457 print(msg, file=self.stdout)
458
459 def error(self, msg):
460 print('***', msg, file=self.stdout)
461
462 # Generic completion functions. Individual complete_foo methods can be
463 # assigned below to one of these functions.
464
465 def _complete_location(self, text, line, begidx, endidx):
466 # Complete a file/module/function location for break/tbreak/clear.
467 if line.strip().endswith((':', ',')):
468 # Here comes a line number or a condition which we can't complete.
469 return []
470 # First, try to find matching functions (i.e. expressions).
471 try:
472 ret = self._complete_expression(text, line, begidx, endidx)
473 except Exception:
474 ret = []
475 # Then, try to complete file names as well.
Haibo Huangf5f93a72020-10-19 15:43:42 -0700476 globs = glob.glob(glob.escape(text) + '*')
Haibo Huangd8830302020-03-03 10:09:46 -0800477 for fn in globs:
478 if os.path.isdir(fn):
479 ret.append(fn + '/')
480 elif os.path.isfile(fn) and fn.lower().endswith(('.py', '.pyw')):
481 ret.append(fn + ':')
482 return ret
483
484 def _complete_bpnumber(self, text, line, begidx, endidx):
485 # Complete a breakpoint number. (This would be more helpful if we could
486 # display additional info along with the completions, such as file/line
487 # of the breakpoint.)
488 return [str(i) for i, bp in enumerate(bdb.Breakpoint.bpbynumber)
489 if bp is not None and str(i).startswith(text)]
490
491 def _complete_expression(self, text, line, begidx, endidx):
492 # Complete an arbitrary expression.
493 if not self.curframe:
494 return []
495 # Collect globals and locals. It is usually not really sensible to also
496 # complete builtins, and they clutter the namespace quite heavily, so we
497 # leave them out.
498 ns = {**self.curframe.f_globals, **self.curframe_locals}
499 if '.' in text:
500 # Walk an attribute chain up to the last part, similar to what
501 # rlcompleter does. This will bail if any of the parts are not
502 # simple attribute access, which is what we want.
503 dotted = text.split('.')
504 try:
505 obj = ns[dotted[0]]
506 for part in dotted[1:-1]:
507 obj = getattr(obj, part)
508 except (KeyError, AttributeError):
509 return []
510 prefix = '.'.join(dotted[:-1]) + '.'
511 return [prefix + n for n in dir(obj) if n.startswith(dotted[-1])]
512 else:
513 # Complete a simple name.
514 return [n for n in ns.keys() if n.startswith(text)]
515
516 # Command definitions, called by cmdloop()
517 # The argument is the remaining string on the command line
518 # Return true to exit from the command loop
519
520 def do_commands(self, arg):
521 """commands [bpnumber]
522 (com) ...
523 (com) end
524 (Pdb)
525
526 Specify a list of commands for breakpoint number bpnumber.
527 The commands themselves are entered on the following lines.
528 Type a line containing just 'end' to terminate the commands.
529 The commands are executed when the breakpoint is hit.
530
531 To remove all commands from a breakpoint, type commands and
532 follow it immediately with end; that is, give no commands.
533
534 With no bpnumber argument, commands refers to the last
535 breakpoint set.
536
537 You can use breakpoint commands to start your program up
538 again. Simply use the continue command, or step, or any other
539 command that resumes execution.
540
541 Specifying any command resuming execution (currently continue,
542 step, next, return, jump, quit and their abbreviations)
543 terminates the command list (as if that command was
544 immediately followed by end). This is because any time you
545 resume execution (even with a simple next or step), you may
546 encounter another breakpoint -- which could have its own
547 command list, leading to ambiguities about which list to
548 execute.
549
550 If you use the 'silent' command in the command list, the usual
551 message about stopping at a breakpoint is not printed. This
552 may be desirable for breakpoints that are to print a specific
553 message and then continue. If none of the other commands
554 print anything, you will see no sign that the breakpoint was
555 reached.
556 """
557 if not arg:
558 bnum = len(bdb.Breakpoint.bpbynumber) - 1
559 else:
560 try:
561 bnum = int(arg)
562 except:
563 self.error("Usage: commands [bnum]\n ...\n end")
564 return
565 self.commands_bnum = bnum
566 # Save old definitions for the case of a keyboard interrupt.
567 if bnum in self.commands:
568 old_command_defs = (self.commands[bnum],
569 self.commands_doprompt[bnum],
570 self.commands_silent[bnum])
571 else:
572 old_command_defs = None
573 self.commands[bnum] = []
574 self.commands_doprompt[bnum] = True
575 self.commands_silent[bnum] = False
576
577 prompt_back = self.prompt
578 self.prompt = '(com) '
579 self.commands_defining = True
580 try:
581 self.cmdloop()
582 except KeyboardInterrupt:
583 # Restore old definitions.
584 if old_command_defs:
585 self.commands[bnum] = old_command_defs[0]
586 self.commands_doprompt[bnum] = old_command_defs[1]
587 self.commands_silent[bnum] = old_command_defs[2]
588 else:
589 del self.commands[bnum]
590 del self.commands_doprompt[bnum]
591 del self.commands_silent[bnum]
592 self.error('command definition aborted, old commands restored')
593 finally:
594 self.commands_defining = False
595 self.prompt = prompt_back
596
597 complete_commands = _complete_bpnumber
598
599 def do_break(self, arg, temporary = 0):
600 """b(reak) [ ([filename:]lineno | function) [, condition] ]
601 Without argument, list all breaks.
602
603 With a line number argument, set a break at this line in the
604 current file. With a function name, set a break at the first
605 executable line of that function. If a second argument is
606 present, it is a string specifying an expression which must
607 evaluate to true before the breakpoint is honored.
608
609 The line number may be prefixed with a filename and a colon,
610 to specify a breakpoint in another file (probably one that
611 hasn't been loaded yet). The file is searched for on
612 sys.path; the .py suffix may be omitted.
613 """
614 if not arg:
615 if self.breaks: # There's at least one
616 self.message("Num Type Disp Enb Where")
617 for bp in bdb.Breakpoint.bpbynumber:
618 if bp:
619 self.message(bp.bpformat())
620 return
621 # parse arguments; comma has lowest precedence
622 # and cannot occur in filename
623 filename = None
624 lineno = None
625 cond = None
626 comma = arg.find(',')
627 if comma > 0:
628 # parse stuff after comma: "condition"
629 cond = arg[comma+1:].lstrip()
630 arg = arg[:comma].rstrip()
631 # parse stuff before comma: [filename:]lineno | function
632 colon = arg.rfind(':')
633 funcname = None
634 if colon >= 0:
635 filename = arg[:colon].rstrip()
636 f = self.lookupmodule(filename)
637 if not f:
638 self.error('%r not found from sys.path' % filename)
639 return
640 else:
641 filename = f
642 arg = arg[colon+1:].lstrip()
643 try:
644 lineno = int(arg)
645 except ValueError:
646 self.error('Bad lineno: %s' % arg)
647 return
648 else:
649 # no colon; can be lineno or function
650 try:
651 lineno = int(arg)
652 except ValueError:
653 try:
654 func = eval(arg,
655 self.curframe.f_globals,
656 self.curframe_locals)
657 except:
658 func = arg
659 try:
660 if hasattr(func, '__func__'):
661 func = func.__func__
662 code = func.__code__
663 #use co_name to identify the bkpt (function names
664 #could be aliased, but co_name is invariant)
665 funcname = code.co_name
666 lineno = code.co_firstlineno
667 filename = code.co_filename
668 except:
669 # last thing to try
670 (ok, filename, ln) = self.lineinfo(arg)
671 if not ok:
672 self.error('The specified object %r is not a function '
673 'or was not found along sys.path.' % arg)
674 return
675 funcname = ok # ok contains a function name
676 lineno = int(ln)
677 if not filename:
678 filename = self.defaultFile()
679 # Check for reasonable breakpoint
680 line = self.checkline(filename, lineno)
681 if line:
682 # now set the break point
683 err = self.set_break(filename, line, temporary, cond, funcname)
684 if err:
685 self.error(err)
686 else:
687 bp = self.get_breaks(filename, line)[-1]
688 self.message("Breakpoint %d at %s:%d" %
689 (bp.number, bp.file, bp.line))
690
691 # To be overridden in derived debuggers
692 def defaultFile(self):
693 """Produce a reasonable default."""
694 filename = self.curframe.f_code.co_filename
695 if filename == '<string>' and self.mainpyfile:
696 filename = self.mainpyfile
697 return filename
698
699 do_b = do_break
700
701 complete_break = _complete_location
702 complete_b = _complete_location
703
704 def do_tbreak(self, arg):
705 """tbreak [ ([filename:]lineno | function) [, condition] ]
706 Same arguments as break, but sets a temporary breakpoint: it
707 is automatically deleted when first hit.
708 """
709 self.do_break(arg, 1)
710
711 complete_tbreak = _complete_location
712
713 def lineinfo(self, identifier):
714 failed = (None, None, None)
715 # Input is identifier, may be in single quotes
716 idstring = identifier.split("'")
717 if len(idstring) == 1:
718 # not in single quotes
719 id = idstring[0].strip()
720 elif len(idstring) == 3:
721 # quoted
722 id = idstring[1].strip()
723 else:
724 return failed
725 if id == '': return failed
726 parts = id.split('.')
727 # Protection for derived debuggers
728 if parts[0] == 'self':
729 del parts[0]
730 if len(parts) == 0:
731 return failed
732 # Best first guess at file to look at
733 fname = self.defaultFile()
734 if len(parts) == 1:
735 item = parts[0]
736 else:
737 # More than one part.
738 # First is module, second is method/class
739 f = self.lookupmodule(parts[0])
740 if f:
741 fname = f
742 item = parts[1]
743 answer = find_function(item, fname)
744 return answer or failed
745
746 def checkline(self, filename, lineno):
747 """Check whether specified line seems to be executable.
748
749 Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
750 line or EOF). Warning: testing is not comprehensive.
751 """
752 # this method should be callable before starting debugging, so default
753 # to "no globals" if there is no current frame
Yi Kong71199322022-08-30 15:53:45 +0800754 frame = getattr(self, 'curframe', None)
755 globs = frame.f_globals if frame else None
Haibo Huangd8830302020-03-03 10:09:46 -0800756 line = linecache.getline(filename, lineno, globs)
757 if not line:
758 self.message('End of file')
759 return 0
760 line = line.strip()
761 # Don't allow setting breakpoint at a blank line
762 if (not line or (line[0] == '#') or
763 (line[:3] == '"""') or line[:3] == "'''"):
764 self.error('Blank or comment')
765 return 0
766 return lineno
767
768 def do_enable(self, arg):
769 """enable bpnumber [bpnumber ...]
770 Enables the breakpoints given as a space separated list of
771 breakpoint numbers.
772 """
773 args = arg.split()
774 for i in args:
775 try:
776 bp = self.get_bpbynumber(i)
777 except ValueError as err:
778 self.error(err)
779 else:
780 bp.enable()
781 self.message('Enabled %s' % bp)
782
783 complete_enable = _complete_bpnumber
784
785 def do_disable(self, arg):
786 """disable bpnumber [bpnumber ...]
787 Disables the breakpoints given as a space separated list of
788 breakpoint numbers. Disabling a breakpoint means it cannot
789 cause the program to stop execution, but unlike clearing a
790 breakpoint, it remains in the list of breakpoints and can be
791 (re-)enabled.
792 """
793 args = arg.split()
794 for i in args:
795 try:
796 bp = self.get_bpbynumber(i)
797 except ValueError as err:
798 self.error(err)
799 else:
800 bp.disable()
801 self.message('Disabled %s' % bp)
802
803 complete_disable = _complete_bpnumber
804
805 def do_condition(self, arg):
806 """condition bpnumber [condition]
807 Set a new condition for the breakpoint, an expression which
808 must evaluate to true before the breakpoint is honored. If
809 condition is absent, any existing condition is removed; i.e.,
810 the breakpoint is made unconditional.
811 """
812 args = arg.split(' ', 1)
813 try:
814 cond = args[1]
815 except IndexError:
816 cond = None
817 try:
818 bp = self.get_bpbynumber(args[0].strip())
819 except IndexError:
820 self.error('Breakpoint number expected')
821 except ValueError as err:
822 self.error(err)
823 else:
824 bp.cond = cond
825 if not cond:
826 self.message('Breakpoint %d is now unconditional.' % bp.number)
827 else:
828 self.message('New condition set for breakpoint %d.' % bp.number)
829
830 complete_condition = _complete_bpnumber
831
832 def do_ignore(self, arg):
833 """ignore bpnumber [count]
834 Set the ignore count for the given breakpoint number. If
835 count is omitted, the ignore count is set to 0. A breakpoint
836 becomes active when the ignore count is zero. When non-zero,
837 the count is decremented each time the breakpoint is reached
838 and the breakpoint is not disabled and any associated
839 condition evaluates to true.
840 """
841 args = arg.split()
842 try:
843 count = int(args[1].strip())
844 except:
845 count = 0
846 try:
847 bp = self.get_bpbynumber(args[0].strip())
848 except IndexError:
849 self.error('Breakpoint number expected')
850 except ValueError as err:
851 self.error(err)
852 else:
853 bp.ignore = count
854 if count > 0:
855 if count > 1:
856 countstr = '%d crossings' % count
857 else:
858 countstr = '1 crossing'
859 self.message('Will ignore next %s of breakpoint %d.' %
860 (countstr, bp.number))
861 else:
862 self.message('Will stop next time breakpoint %d is reached.'
863 % bp.number)
864
865 complete_ignore = _complete_bpnumber
866
867 def do_clear(self, arg):
868 """cl(ear) filename:lineno\ncl(ear) [bpnumber [bpnumber...]]
869 With a space separated list of breakpoint numbers, clear
870 those breakpoints. Without argument, clear all breaks (but
871 first ask confirmation). With a filename:lineno argument,
872 clear all breaks at that line in that file.
873 """
874 if not arg:
875 try:
876 reply = input('Clear all breaks? ')
877 except EOFError:
878 reply = 'no'
879 reply = reply.strip().lower()
880 if reply in ('y', 'yes'):
881 bplist = [bp for bp in bdb.Breakpoint.bpbynumber if bp]
882 self.clear_all_breaks()
883 for bp in bplist:
884 self.message('Deleted %s' % bp)
885 return
886 if ':' in arg:
887 # Make sure it works for "clear C:\foo\bar.py:12"
888 i = arg.rfind(':')
889 filename = arg[:i]
890 arg = arg[i+1:]
891 try:
892 lineno = int(arg)
893 except ValueError:
894 err = "Invalid line number (%s)" % arg
895 else:
Yi Kong71199322022-08-30 15:53:45 +0800896 bplist = self.get_breaks(filename, lineno)[:]
Haibo Huangd8830302020-03-03 10:09:46 -0800897 err = self.clear_break(filename, lineno)
898 if err:
899 self.error(err)
900 else:
901 for bp in bplist:
902 self.message('Deleted %s' % bp)
903 return
904 numberlist = arg.split()
905 for i in numberlist:
906 try:
907 bp = self.get_bpbynumber(i)
908 except ValueError as err:
909 self.error(err)
910 else:
911 self.clear_bpbynumber(i)
912 self.message('Deleted %s' % bp)
913 do_cl = do_clear # 'c' is already an abbreviation for 'continue'
914
915 complete_clear = _complete_location
916 complete_cl = _complete_location
917
918 def do_where(self, arg):
919 """w(here)
920 Print a stack trace, with the most recent frame at the bottom.
921 An arrow indicates the "current frame", which determines the
922 context of most commands. 'bt' is an alias for this command.
923 """
924 self.print_stack_trace()
925 do_w = do_where
926 do_bt = do_where
927
928 def _select_frame(self, number):
929 assert 0 <= number < len(self.stack)
930 self.curindex = number
931 self.curframe = self.stack[self.curindex][0]
932 self.curframe_locals = self.curframe.f_locals
933 self.print_stack_entry(self.stack[self.curindex])
934 self.lineno = None
935
936 def do_up(self, arg):
937 """u(p) [count]
938 Move the current frame count (default one) levels up in the
939 stack trace (to an older frame).
940 """
941 if self.curindex == 0:
942 self.error('Oldest frame')
943 return
944 try:
945 count = int(arg or 1)
946 except ValueError:
947 self.error('Invalid frame count (%s)' % arg)
948 return
949 if count < 0:
950 newframe = 0
951 else:
952 newframe = max(0, self.curindex - count)
953 self._select_frame(newframe)
954 do_u = do_up
955
956 def do_down(self, arg):
957 """d(own) [count]
958 Move the current frame count (default one) levels down in the
959 stack trace (to a newer frame).
960 """
961 if self.curindex + 1 == len(self.stack):
962 self.error('Newest frame')
963 return
964 try:
965 count = int(arg or 1)
966 except ValueError:
967 self.error('Invalid frame count (%s)' % arg)
968 return
969 if count < 0:
970 newframe = len(self.stack) - 1
971 else:
972 newframe = min(len(self.stack) - 1, self.curindex + count)
973 self._select_frame(newframe)
974 do_d = do_down
975
976 def do_until(self, arg):
977 """unt(il) [lineno]
978 Without argument, continue execution until the line with a
979 number greater than the current one is reached. With a line
980 number, continue execution until a line with a number greater
981 or equal to that is reached. In both cases, also stop when
982 the current frame returns.
983 """
984 if arg:
985 try:
986 lineno = int(arg)
987 except ValueError:
988 self.error('Error in argument: %r' % arg)
989 return
990 if lineno <= self.curframe.f_lineno:
991 self.error('"until" line number is smaller than current '
992 'line number')
993 return
994 else:
995 lineno = None
996 self.set_until(self.curframe, lineno)
997 return 1
998 do_unt = do_until
999
1000 def do_step(self, arg):
1001 """s(tep)
1002 Execute the current line, stop at the first possible occasion
1003 (either in a function that is called or in the current
1004 function).
1005 """
1006 self.set_step()
1007 return 1
1008 do_s = do_step
1009
1010 def do_next(self, arg):
1011 """n(ext)
1012 Continue execution until the next line in the current function
1013 is reached or it returns.
1014 """
1015 self.set_next(self.curframe)
1016 return 1
1017 do_n = do_next
1018
1019 def do_run(self, arg):
1020 """run [args...]
1021 Restart the debugged python program. If a string is supplied
1022 it is split with "shlex", and the result is used as the new
1023 sys.argv. History, breakpoints, actions and debugger options
1024 are preserved. "restart" is an alias for "run".
1025 """
1026 if arg:
1027 import shlex
1028 argv0 = sys.argv[0:1]
Yi Kong71199322022-08-30 15:53:45 +08001029 try:
1030 sys.argv = shlex.split(arg)
1031 except ValueError as e:
1032 self.error('Cannot run %s: %s' % (arg, e))
1033 return
Haibo Huangd8830302020-03-03 10:09:46 -08001034 sys.argv[:0] = argv0
1035 # this is caught in the main debugger loop
1036 raise Restart
1037
1038 do_restart = do_run
1039
1040 def do_return(self, arg):
1041 """r(eturn)
1042 Continue execution until the current function returns.
1043 """
1044 self.set_return(self.curframe)
1045 return 1
1046 do_r = do_return
1047
1048 def do_continue(self, arg):
1049 """c(ont(inue))
1050 Continue execution, only stop when a breakpoint is encountered.
1051 """
1052 if not self.nosigint:
1053 try:
1054 Pdb._previous_sigint_handler = \
1055 signal.signal(signal.SIGINT, self.sigint_handler)
1056 except ValueError:
1057 # ValueError happens when do_continue() is invoked from
1058 # a non-main thread in which case we just continue without
1059 # SIGINT set. Would printing a message here (once) make
1060 # sense?
1061 pass
1062 self.set_continue()
1063 return 1
1064 do_c = do_cont = do_continue
1065
1066 def do_jump(self, arg):
1067 """j(ump) lineno
1068 Set the next line that will be executed. Only available in
1069 the bottom-most frame. This lets you jump back and execute
1070 code again, or jump forward to skip code that you don't want
1071 to run.
1072
1073 It should be noted that not all jumps are allowed -- for
1074 instance it is not possible to jump into the middle of a
1075 for loop or out of a finally clause.
1076 """
1077 if self.curindex + 1 != len(self.stack):
1078 self.error('You can only jump within the bottom frame')
1079 return
1080 try:
1081 arg = int(arg)
1082 except ValueError:
1083 self.error("The 'jump' command requires a line number")
1084 else:
1085 try:
1086 # Do the jump, fix up our copy of the stack, and display the
1087 # new position
1088 self.curframe.f_lineno = arg
1089 self.stack[self.curindex] = self.stack[self.curindex][0], arg
1090 self.print_stack_entry(self.stack[self.curindex])
1091 except ValueError as e:
1092 self.error('Jump failed: %s' % e)
1093 do_j = do_jump
1094
1095 def do_debug(self, arg):
1096 """debug code
1097 Enter a recursive debugger that steps through the code
1098 argument (which is an arbitrary expression or statement to be
1099 executed in the current environment).
1100 """
1101 sys.settrace(None)
1102 globals = self.curframe.f_globals
1103 locals = self.curframe_locals
1104 p = Pdb(self.completekey, self.stdin, self.stdout)
1105 p.prompt = "(%s) " % self.prompt.strip()
1106 self.message("ENTERING RECURSIVE DEBUGGER")
1107 try:
1108 sys.call_tracing(p.run, (arg, globals, locals))
1109 except Exception:
Yi Kong71199322022-08-30 15:53:45 +08001110 self._error_exc()
Haibo Huangd8830302020-03-03 10:09:46 -08001111 self.message("LEAVING RECURSIVE DEBUGGER")
1112 sys.settrace(self.trace_dispatch)
1113 self.lastcmd = p.lastcmd
1114
1115 complete_debug = _complete_expression
1116
1117 def do_quit(self, arg):
1118 """q(uit)\nexit
1119 Quit from the debugger. The program being executed is aborted.
1120 """
1121 self._user_requested_quit = True
1122 self.set_quit()
1123 return 1
1124
1125 do_q = do_quit
1126 do_exit = do_quit
1127
1128 def do_EOF(self, arg):
1129 """EOF
1130 Handles the receipt of EOF as a command.
1131 """
1132 self.message('')
1133 self._user_requested_quit = True
1134 self.set_quit()
1135 return 1
1136
1137 def do_args(self, arg):
1138 """a(rgs)
1139 Print the argument list of the current function.
1140 """
1141 co = self.curframe.f_code
1142 dict = self.curframe_locals
1143 n = co.co_argcount + co.co_kwonlyargcount
1144 if co.co_flags & inspect.CO_VARARGS: n = n+1
1145 if co.co_flags & inspect.CO_VARKEYWORDS: n = n+1
1146 for i in range(n):
1147 name = co.co_varnames[i]
1148 if name in dict:
1149 self.message('%s = %r' % (name, dict[name]))
1150 else:
1151 self.message('%s = *** undefined ***' % (name,))
1152 do_a = do_args
1153
1154 def do_retval(self, arg):
1155 """retval
1156 Print the return value for the last return of a function.
1157 """
1158 if '__return__' in self.curframe_locals:
1159 self.message(repr(self.curframe_locals['__return__']))
1160 else:
1161 self.error('Not yet returned!')
1162 do_rv = do_retval
1163
1164 def _getval(self, arg):
1165 try:
1166 return eval(arg, self.curframe.f_globals, self.curframe_locals)
1167 except:
Yi Kong71199322022-08-30 15:53:45 +08001168 self._error_exc()
Haibo Huangd8830302020-03-03 10:09:46 -08001169 raise
1170
1171 def _getval_except(self, arg, frame=None):
1172 try:
1173 if frame is None:
1174 return eval(arg, self.curframe.f_globals, self.curframe_locals)
1175 else:
1176 return eval(arg, frame.f_globals, frame.f_locals)
1177 except:
1178 exc_info = sys.exc_info()[:2]
1179 err = traceback.format_exception_only(*exc_info)[-1].strip()
1180 return _rstr('** raised %s **' % err)
1181
Yi Kong71199322022-08-30 15:53:45 +08001182 def _error_exc(self):
1183 exc_info = sys.exc_info()[:2]
1184 self.error(traceback.format_exception_only(*exc_info)[-1].strip())
1185
1186 def _msg_val_func(self, arg, func):
1187 try:
1188 val = self._getval(arg)
1189 except:
1190 return # _getval() has displayed the error
1191 try:
1192 self.message(func(val))
1193 except:
1194 self._error_exc()
1195
Haibo Huangd8830302020-03-03 10:09:46 -08001196 def do_p(self, arg):
1197 """p expression
1198 Print the value of the expression.
1199 """
Yi Kong71199322022-08-30 15:53:45 +08001200 self._msg_val_func(arg, repr)
Haibo Huangd8830302020-03-03 10:09:46 -08001201
1202 def do_pp(self, arg):
1203 """pp expression
1204 Pretty-print the value of the expression.
1205 """
Yi Kong71199322022-08-30 15:53:45 +08001206 self._msg_val_func(arg, pprint.pformat)
Haibo Huangd8830302020-03-03 10:09:46 -08001207
1208 complete_print = _complete_expression
1209 complete_p = _complete_expression
1210 complete_pp = _complete_expression
1211
1212 def do_list(self, arg):
1213 """l(ist) [first [,last] | .]
1214
1215 List source code for the current file. Without arguments,
1216 list 11 lines around the current line or continue the previous
1217 listing. With . as argument, list 11 lines around the current
1218 line. With one argument, list 11 lines starting at that line.
1219 With two arguments, list the given range; if the second
1220 argument is less than the first, it is a count.
1221
1222 The current line in the current frame is indicated by "->".
1223 If an exception is being debugged, the line where the
1224 exception was originally raised or propagated is indicated by
1225 ">>", if it differs from the current line.
1226 """
1227 self.lastcmd = 'list'
1228 last = None
1229 if arg and arg != '.':
1230 try:
1231 if ',' in arg:
1232 first, last = arg.split(',')
1233 first = int(first.strip())
1234 last = int(last.strip())
1235 if last < first:
1236 # assume it's a count
1237 last = first + last
1238 else:
1239 first = int(arg.strip())
1240 first = max(1, first - 5)
1241 except ValueError:
1242 self.error('Error in argument: %r' % arg)
1243 return
1244 elif self.lineno is None or arg == '.':
1245 first = max(1, self.curframe.f_lineno - 5)
1246 else:
1247 first = self.lineno + 1
1248 if last is None:
1249 last = first + 10
1250 filename = self.curframe.f_code.co_filename
1251 breaklist = self.get_file_breaks(filename)
1252 try:
1253 lines = linecache.getlines(filename, self.curframe.f_globals)
1254 self._print_lines(lines[first-1:last], first, breaklist,
1255 self.curframe)
1256 self.lineno = min(last, len(lines))
1257 if len(lines) < last:
1258 self.message('[EOF]')
1259 except KeyboardInterrupt:
1260 pass
1261 do_l = do_list
1262
1263 def do_longlist(self, arg):
1264 """longlist | ll
1265 List the whole source code for the current function or frame.
1266 """
1267 filename = self.curframe.f_code.co_filename
1268 breaklist = self.get_file_breaks(filename)
1269 try:
1270 lines, lineno = getsourcelines(self.curframe)
1271 except OSError as err:
1272 self.error(err)
1273 return
1274 self._print_lines(lines, lineno, breaklist, self.curframe)
1275 do_ll = do_longlist
1276
1277 def do_source(self, arg):
1278 """source expression
1279 Try to get source code for the given object and display it.
1280 """
1281 try:
1282 obj = self._getval(arg)
1283 except:
1284 return
1285 try:
1286 lines, lineno = getsourcelines(obj)
1287 except (OSError, TypeError) as err:
1288 self.error(err)
1289 return
1290 self._print_lines(lines, lineno)
1291
1292 complete_source = _complete_expression
1293
1294 def _print_lines(self, lines, start, breaks=(), frame=None):
1295 """Print a range of lines."""
1296 if frame:
1297 current_lineno = frame.f_lineno
1298 exc_lineno = self.tb_lineno.get(frame, -1)
1299 else:
1300 current_lineno = exc_lineno = -1
1301 for lineno, line in enumerate(lines, start):
1302 s = str(lineno).rjust(3)
1303 if len(s) < 4:
1304 s += ' '
1305 if lineno in breaks:
1306 s += 'B'
1307 else:
1308 s += ' '
1309 if lineno == current_lineno:
1310 s += '->'
1311 elif lineno == exc_lineno:
1312 s += '>>'
1313 self.message(s + '\t' + line.rstrip())
1314
1315 def do_whatis(self, arg):
1316 """whatis arg
1317 Print the type of the argument.
1318 """
1319 try:
1320 value = self._getval(arg)
1321 except:
1322 # _getval() already printed the error
1323 return
1324 code = None
Haibo Huangd8830302020-03-03 10:09:46 -08001325 # Is it an instance method?
1326 try:
1327 code = value.__func__.__code__
1328 except Exception:
1329 pass
1330 if code:
1331 self.message('Method %s' % code.co_name)
1332 return
Haibo Huang5eba2b42021-01-22 11:22:02 -08001333 # Is it a function?
1334 try:
1335 code = value.__code__
1336 except Exception:
1337 pass
1338 if code:
1339 self.message('Function %s' % code.co_name)
1340 return
Haibo Huangd8830302020-03-03 10:09:46 -08001341 # Is it a class?
1342 if value.__class__ is type:
1343 self.message('Class %s.%s' % (value.__module__, value.__qualname__))
1344 return
1345 # None of the above...
1346 self.message(type(value))
1347
1348 complete_whatis = _complete_expression
1349
1350 def do_display(self, arg):
1351 """display [expression]
1352
1353 Display the value of the expression if it changed, each time execution
1354 stops in the current frame.
1355
1356 Without expression, list all display expressions for the current frame.
1357 """
1358 if not arg:
1359 self.message('Currently displaying:')
1360 for item in self.displaying.get(self.curframe, {}).items():
1361 self.message('%s: %r' % item)
1362 else:
1363 val = self._getval_except(arg)
1364 self.displaying.setdefault(self.curframe, {})[arg] = val
1365 self.message('display %s: %r' % (arg, val))
1366
1367 complete_display = _complete_expression
1368
1369 def do_undisplay(self, arg):
1370 """undisplay [expression]
1371
1372 Do not display the expression any more in the current frame.
1373
1374 Without expression, clear all display expressions for the current frame.
1375 """
1376 if arg:
1377 try:
1378 del self.displaying.get(self.curframe, {})[arg]
1379 except KeyError:
1380 self.error('not displaying %s' % arg)
1381 else:
1382 self.displaying.pop(self.curframe, None)
1383
1384 def complete_undisplay(self, text, line, begidx, endidx):
1385 return [e for e in self.displaying.get(self.curframe, {})
1386 if e.startswith(text)]
1387
1388 def do_interact(self, arg):
1389 """interact
1390
1391 Start an interactive interpreter whose global namespace
1392 contains all the (global and local) names found in the current scope.
1393 """
1394 ns = {**self.curframe.f_globals, **self.curframe_locals}
1395 code.interact("*interactive*", local=ns)
1396
1397 def do_alias(self, arg):
1398 """alias [name [command [parameter parameter ...] ]]
1399 Create an alias called 'name' that executes 'command'. The
1400 command must *not* be enclosed in quotes. Replaceable
1401 parameters can be indicated by %1, %2, and so on, while %* is
1402 replaced by all the parameters. If no command is given, the
1403 current alias for name is shown. If no name is given, all
1404 aliases are listed.
1405
1406 Aliases may be nested and can contain anything that can be
1407 legally typed at the pdb prompt. Note! You *can* override
1408 internal pdb commands with aliases! Those internal commands
1409 are then hidden until the alias is removed. Aliasing is
1410 recursively applied to the first word of the command line; all
1411 other words in the line are left alone.
1412
1413 As an example, here are two useful aliases (especially when
1414 placed in the .pdbrc file):
1415
1416 # Print instance variables (usage "pi classInst")
1417 alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
1418 # Print instance variables in self
1419 alias ps pi self
1420 """
1421 args = arg.split()
1422 if len(args) == 0:
1423 keys = sorted(self.aliases.keys())
1424 for alias in keys:
1425 self.message("%s = %s" % (alias, self.aliases[alias]))
1426 return
1427 if args[0] in self.aliases and len(args) == 1:
1428 self.message("%s = %s" % (args[0], self.aliases[args[0]]))
1429 else:
1430 self.aliases[args[0]] = ' '.join(args[1:])
1431
1432 def do_unalias(self, arg):
1433 """unalias name
1434 Delete the specified alias.
1435 """
1436 args = arg.split()
1437 if len(args) == 0: return
1438 if args[0] in self.aliases:
1439 del self.aliases[args[0]]
1440
1441 def complete_unalias(self, text, line, begidx, endidx):
1442 return [a for a in self.aliases if a.startswith(text)]
1443
1444 # List of all the commands making the program resume execution.
1445 commands_resuming = ['do_continue', 'do_step', 'do_next', 'do_return',
1446 'do_quit', 'do_jump']
1447
1448 # Print a traceback starting at the top stack frame.
1449 # The most recently entered frame is printed last;
1450 # this is different from dbx and gdb, but consistent with
1451 # the Python interpreter's stack trace.
1452 # It is also consistent with the up/down commands (which are
1453 # compatible with dbx and gdb: up moves towards 'main()'
1454 # and down moves towards the most recent stack frame).
1455
1456 def print_stack_trace(self):
1457 try:
1458 for frame_lineno in self.stack:
1459 self.print_stack_entry(frame_lineno)
1460 except KeyboardInterrupt:
1461 pass
1462
1463 def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix):
1464 frame, lineno = frame_lineno
1465 if frame is self.curframe:
1466 prefix = '> '
1467 else:
1468 prefix = ' '
1469 self.message(prefix +
1470 self.format_stack_entry(frame_lineno, prompt_prefix))
1471
1472 # Provide help
1473
1474 def do_help(self, arg):
1475 """h(elp)
1476 Without argument, print the list of available commands.
1477 With a command name as argument, print help about that command.
1478 "help pdb" shows the full pdb documentation.
1479 "help exec" gives help on the ! command.
1480 """
1481 if not arg:
1482 return cmd.Cmd.do_help(self, arg)
1483 try:
1484 try:
1485 topic = getattr(self, 'help_' + arg)
1486 return topic()
1487 except AttributeError:
1488 command = getattr(self, 'do_' + arg)
1489 except AttributeError:
1490 self.error('No help for %r' % arg)
1491 else:
1492 if sys.flags.optimize >= 2:
1493 self.error('No help for %r; please do not run Python with -OO '
1494 'if you need command help' % arg)
1495 return
Yi Kong71199322022-08-30 15:53:45 +08001496 if command.__doc__ is None:
1497 self.error('No help for %r; __doc__ string missing' % arg)
1498 return
Haibo Huangd8830302020-03-03 10:09:46 -08001499 self.message(command.__doc__.rstrip())
1500
1501 do_h = do_help
1502
1503 def help_exec(self):
1504 """(!) statement
1505 Execute the (one-line) statement in the context of the current
1506 stack frame. The exclamation point can be omitted unless the
1507 first word of the statement resembles a debugger command. To
1508 assign to a global variable you must always prefix the command
1509 with a 'global' command, e.g.:
1510 (Pdb) global list_options; list_options = ['-l']
1511 (Pdb)
1512 """
1513 self.message((self.help_exec.__doc__ or '').strip())
1514
1515 def help_pdb(self):
1516 help()
1517
1518 # other helper functions
1519
1520 def lookupmodule(self, filename):
1521 """Helper function for break/clear parsing -- may be overridden.
1522
1523 lookupmodule() translates (possibly incomplete) file or module name
1524 into an absolute file name.
1525 """
1526 if os.path.isabs(filename) and os.path.exists(filename):
1527 return filename
1528 f = os.path.join(sys.path[0], filename)
1529 if os.path.exists(f) and self.canonic(f) == self.mainpyfile:
1530 return f
1531 root, ext = os.path.splitext(filename)
1532 if ext == '':
1533 filename = filename + '.py'
1534 if os.path.isabs(filename):
1535 return filename
1536 for dirname in sys.path:
1537 while os.path.islink(dirname):
1538 dirname = os.readlink(dirname)
1539 fullname = os.path.join(dirname, filename)
1540 if os.path.exists(fullname):
1541 return fullname
1542 return None
1543
1544 def _runmodule(self, module_name):
1545 self._wait_for_mainpyfile = True
1546 self._user_requested_quit = False
1547 import runpy
1548 mod_name, mod_spec, code = runpy._get_module_details(module_name)
1549 self.mainpyfile = self.canonic(code.co_filename)
1550 import __main__
1551 __main__.__dict__.clear()
1552 __main__.__dict__.update({
1553 "__name__": "__main__",
1554 "__file__": self.mainpyfile,
1555 "__package__": mod_spec.parent,
1556 "__loader__": mod_spec.loader,
1557 "__spec__": mod_spec,
1558 "__builtins__": __builtins__,
1559 })
1560 self.run(code)
1561
1562 def _runscript(self, filename):
1563 # The script has to run in __main__ namespace (or imports from
1564 # __main__ will break).
1565 #
1566 # So we clear up the __main__ and set several special variables
1567 # (this gets rid of pdb's globals and cleans old variables on restarts).
1568 import __main__
1569 __main__.__dict__.clear()
1570 __main__.__dict__.update({"__name__" : "__main__",
1571 "__file__" : filename,
1572 "__builtins__": __builtins__,
1573 })
1574
1575 # When bdb sets tracing, a number of call and line events happens
1576 # BEFORE debugger even reaches user's code (and the exact sequence of
1577 # events depends on python version). So we take special measures to
1578 # avoid stopping before we reach the main script (see user_line and
1579 # user_call for details).
1580 self._wait_for_mainpyfile = True
1581 self.mainpyfile = self.canonic(filename)
1582 self._user_requested_quit = False
1583 with io.open_code(filename) as fp:
1584 statement = "exec(compile(%r, %r, 'exec'))" % \
1585 (fp.read(), self.mainpyfile)
1586 self.run(statement)
1587
1588# Collect all command help into docstring, if not run with -OO
1589
1590if __doc__ is not None:
1591 # unfortunately we can't guess this order from the class definition
1592 _help_order = [
1593 'help', 'where', 'down', 'up', 'break', 'tbreak', 'clear', 'disable',
1594 'enable', 'ignore', 'condition', 'commands', 'step', 'next', 'until',
1595 'jump', 'return', 'retval', 'run', 'continue', 'list', 'longlist',
1596 'args', 'p', 'pp', 'whatis', 'source', 'display', 'undisplay',
1597 'interact', 'alias', 'unalias', 'debug', 'quit',
1598 ]
1599
1600 for _command in _help_order:
1601 __doc__ += getattr(Pdb, 'do_' + _command).__doc__.strip() + '\n\n'
1602 __doc__ += Pdb.help_exec.__doc__
1603
1604 del _help_order, _command
1605
1606
1607# Simplified interface
1608
1609def run(statement, globals=None, locals=None):
1610 Pdb().run(statement, globals, locals)
1611
1612def runeval(expression, globals=None, locals=None):
1613 return Pdb().runeval(expression, globals, locals)
1614
1615def runctx(statement, globals, locals):
1616 # B/W compatibility
1617 run(statement, globals, locals)
1618
1619def runcall(*args, **kwds):
1620 return Pdb().runcall(*args, **kwds)
1621
1622def set_trace(*, header=None):
1623 pdb = Pdb()
1624 if header is not None:
1625 pdb.message(header)
1626 pdb.set_trace(sys._getframe().f_back)
1627
1628# Post-Mortem interface
1629
1630def post_mortem(t=None):
1631 # handling the default
1632 if t is None:
1633 # sys.exc_info() returns (type, value, traceback) if an exception is
1634 # being handled, otherwise it returns None
1635 t = sys.exc_info()[2]
1636 if t is None:
1637 raise ValueError("A valid traceback must be passed if no "
1638 "exception is being handled")
1639
1640 p = Pdb()
1641 p.reset()
1642 p.interaction(None, t)
1643
1644def pm():
1645 post_mortem(sys.last_traceback)
1646
1647
1648# Main program for testing
1649
1650TESTCMD = 'import x; x.main()'
1651
1652def test():
1653 run(TESTCMD)
1654
1655# print help
1656def help():
1657 import pydoc
1658 pydoc.pager(__doc__)
1659
1660_usage = """\
1661usage: pdb.py [-c command] ... [-m module | pyfile] [arg] ...
1662
1663Debug the Python program given by pyfile. Alternatively,
1664an executable module or package to debug can be specified using
1665the -m switch.
1666
1667Initial commands are read from .pdbrc files in your home directory
1668and in the current directory, if they exist. Commands supplied with
1669-c are executed after commands from .pdbrc files.
1670
1671To let the script run until an exception occurs, use "-c continue".
1672To let the script run up to a given line X in the debugged file, use
1673"-c 'until X'"."""
1674
1675def main():
1676 import getopt
1677
1678 opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['help', 'command='])
1679
1680 if not args:
1681 print(_usage)
1682 sys.exit(2)
1683
1684 commands = []
1685 run_as_module = False
1686 for opt, optarg in opts:
1687 if opt in ['-h', '--help']:
1688 print(_usage)
1689 sys.exit()
1690 elif opt in ['-c', '--command']:
1691 commands.append(optarg)
1692 elif opt in ['-m']:
1693 run_as_module = True
1694
1695 mainpyfile = args[0] # Get script filename
1696 if not run_as_module and not os.path.exists(mainpyfile):
1697 print('Error:', mainpyfile, 'does not exist')
1698 sys.exit(1)
1699
Yi Kong71199322022-08-30 15:53:45 +08001700 if run_as_module:
1701 import runpy
1702 try:
1703 runpy._get_module_details(mainpyfile)
1704 except Exception:
1705 traceback.print_exc()
1706 sys.exit(1)
1707
Haibo Huangd8830302020-03-03 10:09:46 -08001708 sys.argv[:] = args # Hide "pdb.py" and pdb options from argument list
1709
Haibo Huangd8830302020-03-03 10:09:46 -08001710 if not run_as_module:
Yi Kong71199322022-08-30 15:53:45 +08001711 mainpyfile = os.path.realpath(mainpyfile)
1712 # Replace pdb's dir with script's dir in front of module search path.
Haibo Huangd8830302020-03-03 10:09:46 -08001713 sys.path[0] = os.path.dirname(mainpyfile)
1714
1715 # Note on saving/restoring sys.argv: it's a good idea when sys.argv was
1716 # modified by the script being debugged. It's a bad idea when it was
1717 # changed by the user from the command line. There is a "restart" command
1718 # which allows explicit specification of command line arguments.
1719 pdb = Pdb()
1720 pdb.rcLines.extend(commands)
1721 while True:
1722 try:
1723 if run_as_module:
1724 pdb._runmodule(mainpyfile)
1725 else:
1726 pdb._runscript(mainpyfile)
1727 if pdb._user_requested_quit:
1728 break
1729 print("The program finished and will be restarted")
1730 except Restart:
1731 print("Restarting", mainpyfile, "with arguments:")
Yi Kong71199322022-08-30 15:53:45 +08001732 print("\t" + " ".join(sys.argv[1:]))
Haibo Huangd8830302020-03-03 10:09:46 -08001733 except SystemExit:
1734 # In most cases SystemExit does not warrant a post-mortem session.
1735 print("The program exited via sys.exit(). Exit status:", end=' ')
1736 print(sys.exc_info()[1])
1737 except SyntaxError:
1738 traceback.print_exc()
1739 sys.exit(1)
1740 except:
1741 traceback.print_exc()
1742 print("Uncaught exception. Entering post mortem debugging")
1743 print("Running 'cont' or 'step' will restart the program")
1744 t = sys.exc_info()[2]
1745 pdb.interaction(None, t)
1746 print("Post mortem debugger finished. The " + mainpyfile +
1747 " will be restarted")
1748
1749
1750# When invoked as main program, invoke the debugger on a script
1751if __name__ == '__main__':
1752 import pdb
1753 pdb.main()