def process_options(p, debugger_name, pkg_version, option_list=None): """Handle debugger options. Use option_list if you want are writing another main program and want to extend the existing set of debugger options. The options dicionary from opt_parser is return. Global sys.argv is also updated.""" usage_str="""%prog [debugger-options] [python-script [script-options...]] Runs the extended python debugger""" optparser = OptionParser(usage=usage_str, option_list=option_list, version="%%prog version %s" % pkg_version) optparser.add_option("-X", "--trace", dest="linetrace", action="store_true", default=False, help="Show lines before executing them. " + "This option also sets --batch") optparser.add_option("-F", "--fntrace", dest="fntrace", action="store_true", default=False, help="Show functions before executing them. " + "This option also sets --batch") optparser.add_option("--batch", dest="noninteractive", action="store_true", default=False, help="Don't run interactive commands shell on "+ "stops.") optparser.add_option("--basename", dest="basename", action="store_true", default=False, help="Filenames strip off basename, (e.g. for regression tests)" ) optparser.add_option("-x", "--command", dest="command", action="store", type='string', metavar='FILE', help="Execute commands from FILE.") optparser.add_option("--cd", dest="cd", action="store", type='string', metavar='DIR', help="Change current directory to DIR.") optparser.add_option("--error", dest="errors", metavar='FILE', action="store", type='string', help="Write debugger's error output " + "(stderr) to FILE") optparser.add_option("-e", "--exec", dest="execute", type="string", help="list of debugger commands to " + "execute. Separate the commands with ;;") optparser.add_option("-n", "--nx", dest="noexecute", action="store_true", default=False, help="Don't execute commands found in any " + "initialization files") ## optparser.add_option("--pdbserver", dest="pdbserver", ## help="Start the debugger and execute the pdbserver " \ ## + "command. The arguments should be of the form," \ ## + " 'protocol address scriptname'."), optparser.add_option("-o", "--output", dest="output", metavar='FILE', action="store", type='string', help="Write debugger's output (stdout) " + "to FILE") ## optparser.add_option("--pid", dest="pid", ## help="Attach to running process PID.") optparser.add_option("--sigcheck", dest="sigcheck", action="store_true", default=False, help="Set to watch for signal handler changes") optparser.add_option("-t", "--target", dest="target", help="Specify a target to connect to. Arguments" \ + " should be of form, 'protocol address'."), optparser.add_option("-T", "--threading", dest="threading", action="store_true", default=False, help="Start off with threading debug support") # annotate option produces annotations, used in pydb.el for a better emacs # integration. Annotations are similar in purpose to those of GDB (see # that manual for a description), although the syntax is different. # they have the following format: # # ^Z^Zannotname # <arbitrary text> # ^Z^Z # # where ^Z is the ctrl-Z character, and "annotname" is the name of the # annotation. A line with only two ^Z ends the annotation (no nesting # allowed). See pydb.el for the usage optparser.add_option("--annotate", default=0, type="int", help="Use annotations (to work inside emacs)") # Set up to stop on the first non-option because that's the name # of the script to be debugged on arguments following that are # that scripts options that should be left untouched. We would # not want to interpret and option for the script, e.g. --help, as # one one of our own, e.g. --help. optparser.disable_interspersed_args() # execfile() runs out of Bdb.py and uses sys.argv, so we have to # clobber it and make it what the debugged script expects. Also # the debugged script probably wants to look at sys.argv. # So we'll change sys.argv to look like the program were invoked # directly # Save the original just for use in restart (via exec) p._sys_argv = list(sys.argv) (opts, sys.argv) = optparser.parse_args() ## if opts.target: ## target(opts.target, opts, p) ## sys.exit() ## elif opts.pdbserver: ## pdbserver(opts.pdbserver, p) ## sys.exit() if opts.threading: import threaddbg tpdb = threaddbg.threadDbg() tpdb._sys_argv = p._sys_argv p = tpdb # Get us out of <module>() called from file '<string>' at line 1 p.step_ignore = 1 ## elif opts.pid: ## target(opts.pid, opts, p) ## sys.exit() if opts.linetrace or opts.fntrace: opts.noninteractive = True p.fntrace = opts.fntrace p.linetrace = opts.linetrace p.noninteractive = opts.noninteractive # --nx or -n ? if not opts.noexecute: # Read debugger startup file(s), e.g. $HOME/.pydbrc and ./.pydbrc debugger_startup = ".%src" % debugger_name if 'HOME' in os.environ: debug_startup_home = os.path.join(os.environ['HOME'], debugger_startup) p.setup_source(debug_startup_home) p.setup_source(debugger_startup) if opts.cd: os.chdir(opts.cd) if opts.basename: p.basename = True # As per gdb, first we execute user initialization files and then # we execute any file specified via --command. if opts.command: p.setup_source(os.path.expanduser(opts.command), True); if opts.execute: p.cmdqueue = list(opts.execute.split(';;')) if opts.sigcheck: p.cmdqueue.insert(0, "set sigcheck on") else: p.cmdqueue.insert(0, "set sigcheck off") if opts.output: try: p.stdout = open(opts.output, 'w') except IOError, (errno, strerror): print "I/O in opening debugger output file %s" % opts.output print "error(%s): %s" % (errno, strerror) except ValueError: print "Could not convert data to an integer."
def debugger(dbg_cmds=None, add_exception_hook=True, add_threaddbg=False, new_instance=False): """Enter the debugger at the calling stack frame. This is useful to hard-code a breakpoint at a given point in a program, even if the code is not otherwise being debugged (e.g., when an assertion fails). Leaving this the debugger terminates the program. dbg_cmds is an optional list of debugger commands you want to run. If add_exception is True (the default), we will install an exception hook to call the post-mortem debugger on an unhandled exception. If the debugger was called previously, normally we use that. This way any previous debugger state that was set gets used. If you don't the debugger state to be used, set parameter new_instance True. """ global _pydb_trace try: if not isinstance(_pydb_trace, Pdb): print "Your program should not use _pydb_trace" return except NameError: new_instance = True except: print "Unknown error" return if new_instance: if add_threaddbg: import threaddbg _pydb_trace = threaddbg.threadDbg() else: _pydb_trace = Pdb() _pydb_trace.reset() _pydb_trace._program_sys_argv = list(sys.argv) _pydb_trace._sys_argv = list(_pydb_trace._program_sys_argv) _pydb_trace._sys_argv[:0] = [__title__] _pydb_trace.main_dirname = os.path.dirname(sys.argv[0]) # We don't support "run" so we'll make "run" and "R" be "restart" _pydb_trace.do_R = _pydb_trace.do_run = _pydb_trace.do_restart _pydb_trace.curframe=inspect.currentframe() # Dispatcher needs to field BdbQuit exception _pydb_trace.field_BdbQuit = True if _pydb_trace.running: _pydb_trace.do_next('2') return _pydb_trace.running = True if dbg_cmds != None: _pydb_trace.cmdqueue = list(dbg_cmds) if add_exception_hook: sys.excepthook = exception_hook # Set to skip over return statement _pydb_trace.step_ignore = 1 # There can be no other commands after the following one # unless we adjust _pydb_trace.step_ignore accordingly. # Note in some cases we stop in the "return" below and in some # cases we step one more so we need to be conservitive in the # step count. I don't know why weird behavior. _pydb_trace.set_trace(_pydb_trace.curframe) return
def process_options(p, debugger_name, pkg_version, option_list=None): """Handle debugger options. Use option_list if you want are writing another main program and want to extend the existing set of debugger options. The options dicionary from opt_parser is return. Global sys.argv is also updated.""" usage_str = """%prog [debugger-options] [python-script [script-options...]] Runs the extended python debugger""" optparser = OptionParser(usage=usage_str, option_list=option_list, version="%%prog version %s" % pkg_version) optparser.add_option("-X", "--trace", dest="linetrace", action="store_true", default=False, help="Show lines before executing them. " + "This option also sets --batch") optparser.add_option("-F", "--fntrace", dest="fntrace", action="store_true", default=False, help="Show functions before executing them. " + "This option also sets --batch") optparser.add_option("--batch", dest="noninteractive", action="store_true", default=False, help="Don't run interactive commands shell on " + "stops.") optparser.add_option( "--basename", dest="basename", action="store_true", default=False, help="Filenames strip off basename, (e.g. for regression tests)") optparser.add_option("-x", "--command", dest="command", action="store", type='string', metavar='FILE', help="Execute commands from FILE.") optparser.add_option("--cd", dest="cd", action="store", type='string', metavar='DIR', help="Change current directory to DIR.") optparser.add_option("--error", dest="errors", metavar='FILE', action="store", type='string', help="Write debugger's error output " + "(stderr) to FILE") optparser.add_option("-e", "--exec", dest="execute", type="string", help="list of debugger commands to " + "execute. Separate the commands with ;;") optparser.add_option("-n", "--nx", dest="noexecute", action="store_true", default=False, help="Don't execute commands found in any " + "initialization files") ## optparser.add_option("--pdbserver", dest="pdbserver", ## help="Start the debugger and execute the pdbserver " \ ## + "command. The arguments should be of the form," \ ## + " 'protocol address scriptname'."), optparser.add_option("-o", "--output", dest="output", metavar='FILE', action="store", type='string', help="Write debugger's output (stdout) " + "to FILE") ## optparser.add_option("--pid", dest="pid", ## help="Attach to running process PID.") optparser.add_option("--sigcheck", dest="sigcheck", action="store_true", default=False, help="Set to watch for signal handler changes") optparser.add_option("-t", "--target", dest="target", help="Specify a target to connect to. Arguments" \ + " should be of form, 'protocol address'."), optparser.add_option("-T", "--threading", dest="threading", action="store_true", default=False, help="Start off with threading debug support") # annotate option produces annotations, used in pydb.el for a better emacs # integration. Annotations are similar in purpose to those of GDB (see # that manual for a description), although the syntax is different. # they have the following format: # # ^Z^Zannotname # <arbitrary text> # ^Z^Z # # where ^Z is the ctrl-Z character, and "annotname" is the name of the # annotation. A line with only two ^Z ends the annotation (no nesting # allowed). See pydb.el for the usage optparser.add_option("--annotate", default=0, type="int", help="Use annotations (to work inside emacs)") # Set up to stop on the first non-option because that's the name # of the script to be debugged on arguments following that are # that scripts options that should be left untouched. We would # not want to interpret and option for the script, e.g. --help, as # one one of our own, e.g. --help. optparser.disable_interspersed_args() # execfile() runs out of Bdb.py and uses sys.argv, so we have to # clobber it and make it what the debugged script expects. Also # the debugged script probably wants to look at sys.argv. # So we'll change sys.argv to look like the program were invoked # directly # Save the original just for use in restart (via exec) p._sys_argv = list(sys.argv) (opts, sys.argv) = optparser.parse_args() ## if opts.target: ## target(opts.target, opts, p) ## sys.exit() ## elif opts.pdbserver: ## pdbserver(opts.pdbserver, p) ## sys.exit() if opts.threading: import threaddbg tpdb = threaddbg.threadDbg() tpdb._sys_argv = p._sys_argv p = tpdb # Get us out of <module>() called from file '<string>' at line 1 p.step_ignore = 1 ## elif opts.pid: ## target(opts.pid, opts, p) ## sys.exit() if opts.linetrace or opts.fntrace: opts.noninteractive = True p.fntrace = opts.fntrace p.linetrace = opts.linetrace p.noninteractive = opts.noninteractive # --nx or -n ? if not opts.noexecute: # Read debugger startup file(s), e.g. $HOME/.pydbrc and ./.pydbrc debugger_startup = ".%src" % debugger_name if 'HOME' in os.environ: debug_startup_home = os.path.join(os.environ['HOME'], debugger_startup) p.setup_source(debug_startup_home) p.setup_source(debugger_startup) if opts.cd: os.chdir(opts.cd) if opts.basename: p.basename = True # As per gdb, first we execute user initialization files and then # we execute any file specified via --command. if opts.command: p.setup_source(os.path.expanduser(opts.command), True) if opts.execute: p.cmdqueue = list(opts.execute.split(';;')) if opts.sigcheck: p.cmdqueue.insert(0, "set sigcheck on") else: p.cmdqueue.insert(0, "set sigcheck off") if opts.output: try: p.stdout = open(opts.output, 'w') except IOError, (errno, strerror): print "I/O in opening debugger output file %s" % opts.output print "error(%s): %s" % (errno, strerror) sys.stdout.flush() except ValueError: print "Could not convert data to an integer."
def debugger(dbg_cmds=None, add_exception_hook=True, add_threaddbg=False, status='start', stdout=None): """Enter the debugger at the calling stack frame. This can be used as a way to hard-code a breakpoint in a program, even if the code is not otherwise being debugged (e.g., when an assertion fails). Leaving the debugger, i.e. issuing a "quit" command, terminates the program. dbg_cmds, a list of strings, is an optional list of debugger commands you want to run. If add_exception is True (the default), we will install an exception hook to call the post-mortem debugger on an unhandled exception. If the debugger was called previously, normally we use that. This way any previous debugger state that was set gets used. Setting the parameter `status' to the string 'new' will cause a new instance to be created which might wiping out other instances which might contain information like breakpoints or debugger settings. If instead `status' is set to 'continue', an existing instance will resume. Omitting status or setting it to 'start' will start the debugger which might be a 'new' depending on whether or not an instance has been created. In all cases a string indicating what was done is returned. Since debugging slows down a program, one may want to stop and continue it at various points in your program. """ global _pydb_trace if types.BooleanType == type(status): if status: status = 'new' else: status = 'start' print "debugger() interface has changed see docstring." sys.stdout.flush() try: if not isinstance(_pydb_trace, Pdb): print "Your program should not use _pydb_trace" sys.stdout.flush() return '_pydb_trace conflict' except NameError: status = 'new' except: print "Unknown error" sys.stdout.flush() return 'Unknown error' back_frame = inspect.currentframe().f_back if 'new' == status: if add_threaddbg: import threaddbg _pydb_trace = threaddbg.threadDbg() else: _pydb_trace = Pdb(stdout=stdout) _pydb_trace._program_sys_argv = list(sys.argv) _pydb_trace._sys_argv = list(_pydb_trace._program_sys_argv) _pydb_trace._sys_argv[:0] = [__title__] _pydb_trace.main_dirname = os.path.dirname(sys.argv[0]) _pydb_trace.curframe = back_frame _pydb_trace.stopframe = back_frame if 'continue' == status: pass elif _pydb_trace.running: return 'running' _pydb_trace.running = True # We don't support "run" so we'll make "run" and "R" be "restart" _pydb_trace.do_R = _pydb_trace.do_run = _pydb_trace.do_restart _pydb_trace.curframe = back_frame _pydb_trace.stopframe = back_frame # Dispatcher needs to field BdbQuit exception _pydb_trace.field_BdbQuit = True if dbg_cmds != None: _pydb_trace.cmdqueue = list(dbg_cmds) if add_exception_hook: sys.excepthook = exception_hook _pydb_trace.set_trace(_pydb_trace.curframe) return status
def debugger(dbg_cmds=None, add_exception_hook=True, add_threaddbg=False, status='start', stdout=None): """Enter the debugger at the calling stack frame. This can be used as a way to hard-code a breakpoint in a program, even if the code is not otherwise being debugged (e.g., when an assertion fails). Leaving the debugger, i.e. issuing a "quit" command, terminates the program. dbg_cmds, a list of strings, is an optional list of debugger commands you want to run. If add_exception is True (the default), we will install an exception hook to call the post-mortem debugger on an unhandled exception. If the debugger was called previously, normally we use that. This way any previous debugger state that was set gets used. Setting the parameter `status' to the string 'new' will cause a new instance to be created which might wiping out other instances which might contain information like breakpoints or debugger settings. If instead `status' is set to 'continue', an existing instance will resume. Omitting status or setting it to 'start' will start the debugger which might be a 'new' depending on whether or not an instance has been created. In all cases a string indicating what was done is returned. Since debugging slows down a program, one may want to stop and continue it at various points in your program. """ global _pydb_trace if types.BooleanType == type(status): if status: status = 'new' else: status = 'start' print "debugger() interface has changed see docstring." try: if not isinstance(_pydb_trace, Pdb): print "Your program should not use _pydb_trace" return '_pydb_trace conflict' except NameError: status = 'new' except: print "Unknown error" return 'Unknown error' back_frame = inspect.currentframe().f_back if 'new' == status: if add_threaddbg: import threaddbg _pydb_trace = threaddbg.threadDbg() else: _pydb_trace = Pdb(stdout=stdout) _pydb_trace._program_sys_argv = list(sys.argv) _pydb_trace._sys_argv = list(_pydb_trace._program_sys_argv) _pydb_trace._sys_argv[:0] = [__title__] _pydb_trace.main_dirname = os.path.dirname(sys.argv[0]) _pydb_trace.curframe = back_frame _pydb_trace.stopframe = back_frame if 'continue' == status: pass elif _pydb_trace.running: return 'running' _pydb_trace.running = True # We don't support "run" so we'll make "run" and "R" be "restart" _pydb_trace.do_R = _pydb_trace.do_run = _pydb_trace.do_restart _pydb_trace.curframe = back_frame _pydb_trace.stopframe = back_frame # Dispatcher needs to field BdbQuit exception _pydb_trace.field_BdbQuit = True if dbg_cmds != None: _pydb_trace.cmdqueue = list(dbg_cmds) if add_exception_hook: sys.excepthook = exception_hook _pydb_trace.set_trace(_pydb_trace.curframe) return status