Example #1
0
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."
Example #2
0
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
Example #3
0
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."
Example #4
0
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
Example #5
0
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