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