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