Пример #1
0
    def run(self, args):
        """Current line number in source file"""
        if not self.proc.curframe:
            self.errmsg("No line number information available.")
            return

        # info line <loc>
        if len(args) == 0:
            # No line number. Use current frame line number
            line_number = inspect.getlineno(self.proc.curframe)
            filename = self.core.canonic_filename(self.proc.curframe)
        elif len(args) == 1:
            # lineinfo returns (item, file, lineno) or (None,)
            line_number, filename = self.lineinfo(args[2:])
            if not filename:
                self.errmsg("Can't parse '%s'" % args[2])
                pass
            filename = self.core.canonic(filename)
        else:
            self.errmsg("Wrong number of arguments.")
            return
        if not osp.isfile(filename):
            filename = search_file(filename, self.core.search_path,
                                   self.main_dirname)
            pass

        line_info = code_line_info(filename, line_number)
        msg1 = 'Line %d of "%s"' % (
            line_number,
            self.core.filename(filename),
        )
        if line_info:
            msg2 = "starts at offset %d of %s and contains %d instructions" % (
                line_info[0].offsets[0],
                line_info[0].name,
                len(line_info[0].offsets),
            )
            self.msg(wrapped_lines(msg1, msg2, self.settings["width"]))
        else:
            self.errmsg("No line information for line %d of %s" %
                        (line_number, self.core.filename(filename)))
        if line_info and len(line_info) > 1:
            self.msg(
                wrapped_lines(
                    "There are multiple line offsets for line number.",
                    "Other line offsets: %s" % ", ".join([
                        "%s of %s" % (li.offsets[0], li.name)
                        for li in line_info[1:]
                    ]),
                    self.settings["width"],
                ))
        return False
Пример #2
0
def set_break(cmd_obj,
              func,
              filename,
              lineno,
              condition,
              temporary,
              args,
              force=False):
    if lineno is None:
        part1 = ("I don't understand '%s' as a line number, function name," %
                 ' '.join(args[1:]))
        msg = Mmisc.wrapped_lines(part1, "or file/module plus line number.",
                                  cmd_obj.settings['width'])
        cmd_obj.errmsg(msg)
        return False
    if filename is None:
        filename = cmd_obj.proc.curframe.f_code.co_filename
        filename = cmd_obj.core.canonic(filename)
        pass
    if func is None:
        try:
            ok_linenos = pyficache.trace_line_numbers(filename)
        except:
            ok_linenos = None

        if not ok_linenos or lineno not in ok_linenos:
            part1 = ('File %s' % cmd_obj.core.filename(filename))
            msg = Mmisc.wrapped_lines(part1,
                                      "is not stoppable at line %d." % lineno,
                                      cmd_obj.settings['width'])
            cmd_obj.errmsg(msg)
            if force:
                cmd_obj.msg("Breakpoint set although it may never be reached")
            else:
                return False
        pass
    bp = cmd_obj.core.bpmgr.add_breakpoint(filename, lineno, temporary,
                                           condition, func)
    if func and inspect.isfunction(func):
        cmd_obj.msg('Breakpoint %d set on calling function %s()' %
                    (bp.number, func.func_name))
        part1 = 'Currently this is line %d of file' % lineno
        msg = Mmisc.wrapped_lines(part1, cmd_obj.core.filename(filename),
                                  cmd_obj.settings['width'])
    else:
        part1 = ('Breakpoint %d set at line %d of file' % (bp.number, lineno))
        msg = Mmisc.wrapped_lines(part1, cmd_obj.core.filename(filename),
                                  cmd_obj.settings['width'])
        pass
    cmd_obj.msg(msg)
    return True
Пример #3
0
    def run(self, args):
        """Execution status of the program."""
        mainfile = self.core.filename(None)
        if self.core.is_running():
            if mainfile:
                part1 = "Python program '%s' is stopped" % mainfile
            else:
                part1 = 'Program is stopped'
                pass
            if self.proc.event:
                msg = 'via a %s event.' % self.proc.event
            else:
                msg = '.'
            self.msg(Mmisc.wrapped_lines(part1, msg,
                                         self.settings['width']))
            if self.proc.curframe:
                self.msg("PC offset is %d." % self.proc.curframe.f_lasti)

            if self.proc.event == 'return':
                val = self.proc.event_arg
                part1 = 'Return value is'
                self.msg(Mmisc.wrapped_lines(part1, self.proc._saferepr(val),
                                             self.settings['width']))
                pass
            elif self.proc.event == 'exception':
                exc_type, exc_value, exc_tb = self.proc.event_arg
                self.msg('Exception type: %s' %
                         self.proc._saferepr(exc_type))
                if exc_value:
                    self.msg('Exception value: %s' %
                             self.proc._saferepr(exc_value))
                    pass
                pass
            self.msg('It stopped %s.' % self.core.stop_reason)
            if self.proc.event in ['signal', 'exception', 'c_exception']:
                self.msg('Note: we are stopped *after* running the '
                         'line shown.')
                pass
        else:
            if mainfile:
                part1 = "Python program '%s'" % mainfile
                msg   = "is not currently running. "
                self.msg(Mmisc.wrapped_lines(part1, msg,
                                             self.settings['width']))
            else:
                self.msg('No Python program is currently running.')
                pass
            self.msg(self.core.execution_status)
            pass
        return False
Пример #4
0
    def run(self, args):
        """Execution status of the program."""
        mainfile = self.core.filename(None)
        if self.core.is_running():
            if mainfile:
                part1 = "Python program '%s' is stopped" % mainfile
            else:
                part1 = 'Program is stopped'
                pass
            if self.proc.event:
                msg = 'via a %s event.' % self.proc.event
            else:
                msg = '.'
            self.msg(Mmisc.wrapped_lines(part1, msg,
                                         self.settings['width']))
            if self.proc.curframe:
                self.msg("PC offset is %d." % self.proc.curframe.f_lasti)

            if self.proc.event == 'return':
                val = self.proc.event_arg
                part1 = 'Return value is'
                self.msg(Mmisc.wrapped_lines(part1, self.proc._saferepr(val),
                                             self.settings['width']))
                pass
            elif self.proc.event == 'exception':
                exc_type, exc_value, exc_tb = self.proc.event_arg
                self.msg('Exception type: %s' %
                         self.proc._saferepr(exc_type))
                if exc_value:
                    self.msg('Exception value: %s' %
                             self.proc._saferepr(exc_value))
                    pass
                pass
            self.msg('It stopped %s.' % self.core.stop_reason)
            if self.proc.event in ['signal', 'exception', 'c_exception']:
                self.msg('Note: we are stopped *after* running the '
                         'line shown.')
                pass
        else:
            if mainfile:
                part1 = "Python program '%s'" % mainfile
                msg   = "is not currently running. "
                self.msg(Mmisc.wrapped_lines(part1, msg,
                                             self.settings['width']))
            else:
                self.msg('No Python program is currently running.')
                pass
            self.msg(self.core.execution_status)
            pass
        return False
Пример #5
0
    def run(self, args):
        """Current line number in source file"""
        # info line identifier
        if not self.proc.curframe:
            self.errmsg("No line number information available.")
            return
        if len(args) == 3:
            # lineinfo returns (item, file, lineno) or (None,)
            answer = self.lineinfo(args[2])
            if answer[0]:
                item, filename, lineno = answer
                if not os.path.isfile(filename):
                    filename = Mclifns.search_file(filename,
                                                   self.core.search_path,
                                                   self.main_dirname)
                self.msg('Line %s of "%s" <%s>' %
                         (lineno, filename, item))
            return
        filename=self.core.canonic_filename(self.proc.curframe)
        if not os.path.isfile(filename):
            filename = Mclifns.search_file(filename, self.core.search_path,
                                           self.main_dirname)
            pass

        filename = self.core.canonic_filename(self.proc.curframe)
        msg1 = 'Line %d of \"%s\"'  % (inspect.getlineno(self.proc.curframe),
                                       self.core.filename(filename))
        msg2 = ('at instruction %d' % self.proc.curframe.f_lasti)
        if self.proc.event:
            msg2 += ', %s event' % self.proc.event
            pass
        self.msg(Mmisc.wrapped_lines(msg1, msg2, self.settings['width']))
        return False
Пример #6
0
    def run(self, args):
        """Current line number in source file"""
        # info line identifier
        if not self.proc.curframe:
            self.errmsg("No line number information available.")
            return
        if len(args) == 3:
            # lineinfo returns (item, file, lineno) or (None,)
            answer = self.lineinfo(args[2])
            if answer[0]:
                item, filename, lineno = answer
                if not os.path.isfile(filename):
                    filename = Mclifns.search_file(filename,
                                                   self.core.search_path,
                                                   self.main_dirname)
                self.msg('Line %s of "%s" <%s>' % (lineno, filename, item))
            return
        filename = self.core.canonic_filename(self.proc.curframe)
        if not os.path.isfile(filename):
            filename = Mclifns.search_file(filename, self.core.search_path,
                                           self.main_dirname)
            pass

        filename = self.core.canonic_filename(self.proc.curframe)
        msg1 = 'Line %d of \"%s\"' % (inspect.getlineno(
            self.proc.curframe), self.core.filename(filename))
        msg2 = ('at instruction %d' % self.proc.curframe.f_lasti)
        if self.proc.event:
            msg2 += ', %s event' % self.proc.event
            pass
        self.msg(Mmisc.wrapped_lines(msg1, msg2, self.settings['width']))
        return False
Пример #7
0
 def run(self, args):
     """Program counter."""
     mainfile = self.core.filename(None)
     if self.core.is_running():
         curframe = self.proc.curframe
         if curframe:
             line_no = inspect.getlineno(curframe)
             offset  = curframe.f_lasti
             self.msg("PC offset is %d." % offset)
             offset = max(offset, 0)
             code = curframe.f_code
             co_code = code.co_code
             disassemble_bytes(self.msg, self.msg_nocr,
                               co_code, offset, line_no, line_no-1, line_no+1,
                               constants=code.co_consts, cells=code.co_cellvars,
                               varnames=code.co_varnames, freevars=code.co_freevars,
                               linestarts=dict(findlinestarts(code)),
                               end_offset=offset+10)
             pass
         pass
     else:
         if mainfile:
             part1 = "Python program '%s'" % mainfile
             msg   = "is not currently running. "
             self.msg(Mmisc.wrapped_lines(part1, msg,
                                          self.settings['width']))
         else:
             self.msg('No Python program is currently running.')
             pass
         self.msg(self.core.execution_status)
         pass
     return False
Пример #8
0
 def ok_for_running(self, cmd_obj, name, nargs):
     '''We separate some of the common debugger command checks here:
     whether it makes sense to run the command in this execution state,
     if the command has the right number of arguments and so on.
     '''
     if hasattr(cmd_obj, 'execution_set'):
         if not (self.core.execution_status in cmd_obj.execution_set):
             part1 = (
                 "Command '%s' is not available for execution status:" %
                 name)
             mess = Mmisc.wrapped_lines(part1, self.core.execution_status,
                                        self.debugger.settings['width'])
             self.errmsg(mess)
             return False
         pass
     if self.frame is None and cmd_obj.need_stack:
         self.intf[-1].errmsg("Command '%s' needs an execution stack." %
                              name)
         return False
     if nargs < cmd_obj.min_args:
         self.errmsg(
             ("Command '%s' needs at least %d argument(s); " + "got %d.") %
             (name, cmd_obj.min_args, nargs))
         return False
     elif cmd_obj.max_args is not None and nargs > cmd_obj.max_args:
         self.errmsg(
             ("Command '%s' can take at most %d argument(s);" + " got %d.")
             % (name, cmd_obj.max_args, nargs))
         return False
     return True
Пример #9
0
 def ok_for_running(self, cmd_obj, name, nargs):
     '''We separate some of the common debugger command checks here:
     whether it makes sense to run the command in this execution state,
     if the command has the right number of arguments and so on.
     '''
     if hasattr(cmd_obj, 'execution_set'):
         if not (self.core.execution_status in cmd_obj.execution_set):
             part1 = ("Command '%s' is not available for execution status:"
                      % name)
             mess = Mmisc.wrapped_lines(part1,
                                     self.core.execution_status,
                                     self.debugger.settings['width'])
             self.errmsg(mess)
             return False
         pass
     if self.frame is None and cmd_obj.need_stack:
         self.intf[-1].errmsg("Command '%s' needs an execution stack."
                              % name)
         return False
     if nargs < cmd_obj.min_args:
         self.errmsg(("Command '%s' needs at least %d argument(s); " +
                          "got %d.") %
                          (name, cmd_obj.min_args, nargs))
         return False
     elif cmd_obj.max_args is not None and nargs > cmd_obj.max_args:
         self.errmsg(("Command '%s' can take at most %d argument(s);" +
                           " got %d.") %
                          (name, cmd_obj.max_args, nargs))
         return False
     return True
Пример #10
0
    def run(self, args):
        mainfile = self.core.filename(None)
        if self.core.is_running():
            if mainfile:
                part1 = "Python program '%s' is stopped" % mainfile
            else:
                part1 = "Program is stopped"
                pass
            if self.proc.event:
                msg = "via a %s event." % self.proc.event
            else:
                msg = "."
            self.msg(Mmisc.wrapped_lines(part1, msg, self.settings["width"]))
            if self.proc.curframe:
                self.msg("PC offset is %d." % self.proc.curframe.f_lasti)

            if self.proc.event == "return":
                val = self.proc.event_arg
                part1 = "Return value is"
                self.msg(Mmisc.wrapped_lines(part1, self.proc._saferepr(val), self.settings["width"]))
                pass
            elif self.proc.event == "exception":
                exc_type, exc_value, exc_tb = self.proc.event_arg
                self.msg("Exception type: %s" % self.proc._saferepr(exc_type))
                if exc_value:
                    self.msg("Exception value: %s" % self.proc._saferepr(exc_value))
                    pass
                pass
            self.msg("It stopped %s." % self.core.stop_reason)
            if self.proc.event in ["signal", "exception", "c_exception"]:
                self.msg("Note: we are stopped *after* running the " "line shown.")
                pass
        else:
            if mainfile:
                part1 = "Python program '%s'" % mainfile
                msg = "is not currently running. "
                self.msg(Mmisc.wrapped_lines(part1, msg, self.settings["width"]))
            else:
                self.msg("No Python program is currently running.")
                pass
            self.msg(self.core.execution_status)
            pass
        return False
Пример #11
0
def set_break(cmd_obj, func, filename, lineno, condition, temporary,
              args, force=False):
    if lineno is None:
        part1 = ("I don't understand '%s' as a line number, function name,"
                 % ' '.join(args[1:]))
        msg = Mmisc.wrapped_lines(part1, "or file/module plus line number.",
                                  cmd_obj.settings['width'])
        cmd_obj.errmsg(msg)
        return False
    if filename is None:
        filename = cmd_obj.proc.curframe.f_code.co_filename
        filename = cmd_obj.core.canonic(filename)
        pass
    if func is None:
        ok_linenos = pyficache.trace_line_numbers(filename)
        if not ok_linenos or lineno not in ok_linenos:
            part1 = ('File %s' % cmd_obj.core.filename(filename))
            msg = Mmisc.wrapped_lines(part1,
                                      "is not stoppable at line %d." %
                                      lineno, cmd_obj.settings['width'])
            cmd_obj.errmsg(msg)
            if force:
                cmd_obj.msg("Breakpoint set although it may never be reached")
            else:
                return False
        pass
    bp =  cmd_obj.core.bpmgr.add_breakpoint(filename, lineno, temporary,
                                         condition, func)
    if func and inspect.isfunction(func):
        cmd_obj.msg('Breakpoint %d set on calling function %s()'
                 % (bp.number, func.func_name))
        part1 = 'Currently this is line %d of file'  % lineno
        msg = Mmisc.wrapped_lines(part1, cmd_obj.core.filename(filename),
                                  cmd_obj.settings['width'])
    else:
        part1 = ( 'Breakpoint %d set at line %d of file'
                  % (bp.number, lineno))
        msg = Mmisc.wrapped_lines(part1, cmd_obj.core.filename(filename),
                                  cmd_obj.settings['width'])
        pass
    cmd_obj.msg(msg)
    return True
Пример #12
0
 def run(self, args):
     sys_argv = self.debugger.restart_argv()
     if sys_argv and len(sys_argv) > 0:
         confirmed = self.confirm('Restart (execv)', False)
         if confirmed:
             self.msg(Mmisc.wrapped_lines("Re exec'ing:", repr(sys_argv),
                                          self.settings['width']))
             # Run atexit finalize routines. This seems to be Kosher:
             # http://mail.python.org/pipermail/python-dev/2009-February/085791.html # NOQA
             try:
                 atexit._run_exitfuncs()
             except:
                 pass
             os.execvp(sys_argv[0], sys_argv)
             pass
         pass
     else:
         self.errmsg("No executable file and command options recorded.")
         pass
     return
Пример #13
0
 def ok_for_running(self, cmd_obj, name, cmd_hash):
     '''We separate some of the common debugger command checks here:
     whether it makes sense to run the command in this execution state,
     if the command has the right number of arguments and so on.
     '''
     if hasattr(cmd_obj, 'execution_set'):
         if not (self.core.execution_status in cmd_obj.execution_set):
             part1 = ("Command '%s' is not available for execution "
                      "status:" % name)
             Mmsg.errmsg(
                 self,
                 Mmisc.wrapped_lines(part1, self.core.execution_status,
                                     self.debugger.settings['width']))
             return False
         pass
     if self.frame is None and cmd_obj.need_stack:
         self.intf[-1].errmsg("Command '%s' needs an execution stack." %
                              name)
         return False
     return True
Пример #14
0
    def run(self, args):
        mainfile = self.core.filename(None)
        if self.core.is_running():
            proc = self.proc

            is_offset = True
            n = len(args)
            if n == 2:
                if args[0] == "=":
                    args[0] = args[1]
                else:
                    try:
                        opts, args = getopt(args, "hlo",
                                            ["help", "line", "offset"])
                    except GetoptError as err:
                        # print help information and exit:
                        print(
                            str(err)
                        )  # will print something like "option -a not recognized"
                        return

                    for o, a in opts:
                        if o in ("-h", "--help"):
                            proc.commands["help"].run(["help", "set", "pc"])
                            return
                        elif o in (
                                "-l",
                                "--line",
                        ):
                            is_offset = False
                        elif o in ("-o", "--offset"):
                            is_offset = True
                        else:
                            self.errmsg("unhandled option '%s'" % o)
                        pass
                    pass
                pass

            frame = proc.frame
            if frame:
                code = frame.f_code
                if is_offset:
                    min_value = 0
                    max_value = len(code.co_code) - 1
                elif len(code.co_lnotab) > 0:
                    min_value = code.co_firstlineno
                    # FIXME: put this in a function in xdis somewhere.
                    # Also: won't need ord() in Python 2.x
                    # max_value = min_value + sum([ord(i) for i in code.co_lnotab[1::2]])
                    max_value = min_value + sum(code.co_lnotab[1::2])
                else:
                    min_value = max_value = code.co_firstline

                offset = get_an_int(
                    self.errmsg,
                    args[0],
                    "The 'pc' command requires an integer offset or a line.",
                    min_value,
                    max_value,
                )
                if offset is None:
                    return None
                # FIXME: We check that offset points to an
                # opcode or a valid line as opposed to an operand
                if not is_offset:
                    self.errmsg("Sorry, line numbers not handled right now.")
                    return None

                self.list_offset = frame.f_lasti = offset
                frame.fallthrough = False
                self.list_lineno = frame.f_lineno = frame.line_number()
                self.msg("Execution set to resume at offset %d" % offset)
                self.return_status = "skip"
                return None
            else:
                self.errmsg("Oddly, a frame is not set - nothing done.")
                pass
        else:
            if mainfile:
                part1 = "Python program '%s'" % mainfile
                msg = "is not currently running. "
                self.msg(wrapped_lines(part1, msg, self.settings["width"]))
            else:
                self.msg("No Python program is currently running.")
                pass
            self.msg(self.core.execution_status)
            pass
        return None
Пример #15
0
    def __init__(
        self, string_or_path: str, is_file: bool, trace_only: bool, args: List[str]
    ):
        """Create a debugger object. But depending on the value of
        key 'start' inside hash 'opts', we may or may not initially
        start debugging.

        See also TrepanXPy.start and TrepanXPy.stop.
        """

        def instruction_fmt_func(frame, opc, byte_name, int_arg, arguments, offset, line_number,
                                 extra_debug, vm=None):
            return format_instruction_with_highlight(
                frame=frame,
                opc=opc,
                byte_name=byte_name,
                int_arg = int_arg,
                arguments = arguments,
                offset = offset,
                line_number = line_number,
                extra_debug = extra_debug,
                settings=self.settings,
                vm = vm,
                show_line = True
            )

        self.mainpyfile = None
        self.thread = None

        completer = lambda text, state: self.complete(text, state)
        interface_opts = {
            "complete": completer,
            "debugger_name": "trepan-xpy",
        }
        interface = UserInterface(opts=interface_opts)
        self.intf = [interface]

        # main_dirname is the directory where the script resides.
        # Filenames in co_filename are often relative to this.
        self.main_dirname = os.curdir

        self.filename_cache: Dict[str, Any] = {}
        self.settings = DEBUGGER_SETTINGS
        self.core = TrepanXPyCore(self, {})
        if trace_only:
            processor = XPyPrintProcessor(self.core)
        else:
            processor = XPyCommandProcessor(self.core)
        self.core.processor = processor
        self.callback_hook = self.core.trace_dispatch

        # Save information for restarting
        self.program_sys_argv = list(sys.argv)
        self.orig_sys_argv = list(sys.argv)

        if is_file:
            mainpyfile = self.core.canonic(string_or_path)
            run_fn = run_python_file
        else:
            mainpyfile = string_or_path
            run_fn = run_python_string

        while True:
            print("Running x-python %s with %s" % (string_or_path, args))
            try:
                run_fn(
                    string_or_path,
                    args,
                    callback=self.callback_hook,
                    format_instruction=instruction_fmt_func,
                )
            except DebuggerQuit:
                break
            except DebuggerRestart:
                self.core.execution_status = "Restart requested"
                if self.program_sys_argv:
                    sys.argv = list(self.program_sys_argv)
                    part1 = "Restarting %s with arguments:" % self.core.filename(
                        mainpyfile
                    )
                    args = " ".join(self.program_sys_argv[1:])
                    self.intf[-1].msg(
                        wrapped_lines(part1, args, self.settings["width"])
                    )
                else:
                    break
            except (FileNotFoundError, NoSourceError) as e:
                self.intf[-1].msg(str(e))
                sys.exit(1)
            except SystemExit:
                # In most cases SystemExit does not warrant a post-mortem session.
                break
            else:
                if trace_only:
                    break
                msg = "The program finished - press enter to restart; anything else terminates. ? "
                response = input(msg)
                if response != "":
                    break
                pass
Пример #16
0
def main(dbg=None, sys_argv=list(sys.argv)):
    """Routine which gets run if we were invoked directly"""

    # Save the original just for use in the restart that works via exec.
    orig_sys_argv = list(sys_argv)
    opts, dbg_opts, sys_argv  = Moptions.process_options(__title__,
                                                         __version__,
                                                         sys_argv)
    if opts.server:
        connection_opts={'IO': 'TCP', 'PORT': opts.port}
        intf = Mserver.ServerInterface(connection_opts=connection_opts)
        dbg_opts['interface'] = intf
        if 'FIFO' == intf.server_type:
            print('Starting FIFO server for process %s.' % os.getpid())
        elif 'TCP' == intf.server_type:
            print('Starting TCP server listening on port %s.' %
                  intf.inout.PORT)
            pass
    elif opts.client:
        Mclient.main(opts, sys_argv)
        return

    dbg_opts['orig_sys_argv'] = orig_sys_argv

    if dbg is None:
        dbg = Mdebugger.Debugger(dbg_opts)
        dbg.core.add_ignore(main)
        pass
    Moptions._postprocess_options(dbg, opts)

    # process_options has munged sys.argv to remove any options that
    # options that belong to this debugger. The original options to
    # invoke the debugger and script are in global sys_argv

    if len(sys_argv) == 0:
        # No program given to debug. Set to go into a command loop
        # anyway
        mainpyfile = None
    else:
        mainpyfile = sys_argv[0]  # Get script filename.
        if not os.path.isfile(mainpyfile):
            mainpyfile=Mclifns.whence_file(mainpyfile)
            is_readable = Mfile.readable(mainpyfile)
            if is_readable is None:
                print("%s: Python script file '%s' does not exist"
                      % (__title__, mainpyfile,), file=sys.stderr)
                sys.exit(1)
            elif not is_readable:
                print("%s: Can't read Python script file '%s'"
                      % (__title__, mainpyfile, ), file=sys.stderr)
                sys.exit(1)
                return

        if Mfile.is_compiled_py(mainpyfile):
            try:
                from uncompyle2 import uncompyle_file
            except ImportError:
                print("%s: Compiled python file '%s', but uncompyle2 not found"
                    % (__title__, mainpyfile), file=sys.stderr)
                sys.exit(1)

            short_name = os.path.basename(mainpyfile).strip('.pyc')
            fd = tempfile.NamedTemporaryFile(suffix='.py',
                                             prefix=short_name + "_",
                                             delete=False)
            try:
                uncompyle_file(mainpyfile, fd)
            except:
                print("%s: error uncompyling '%s'"
                      % (__title__, mainpyfile), file=sys.stderr)
                sys.exit(1)
            mainpyfile = fd.name
            fd.close()

        # If mainpyfile is an optimized Python script try to find and
        # use non-optimized alternative.
        mainpyfile_noopt = Mfile.file_pyc2py(mainpyfile)
        if mainpyfile != mainpyfile_noopt \
               and Mfile.readable(mainpyfile_noopt):
            print("%s: Compiled Python script given and we can't use that."
                  % __title__, file=sys.stderr)
            print("%s: Substituting non-compiled name: %s" % (
                __title__, mainpyfile_noopt,), file=sys.stderr)
            mainpyfile = mainpyfile_noopt
            pass

        # Replace trepan's dir with script's dir in front of
        # module search path.
        sys.path[0] = dbg.main_dirname = os.path.dirname(mainpyfile)

    # XXX If a signal has been received we continue in the loop, otherwise
    # the loop exits for some reason.
    dbg.sig_received = False

    # if not mainpyfile:
    #     print('For now, you need to specify a Python script name!')
    #     sys.exit(2)
    #     pass

    while True:

        # Run the debugged script over and over again until we get it
        # right.

        try:
            if dbg.program_sys_argv and mainpyfile:
                normal_termination = dbg.run_script(mainpyfile)
                if not normal_termination: break
            else:
                dbg.core.execution_status = 'No program'
                dbg.core.processor.process_commands()
                pass

            dbg.core.execution_status = 'Terminated'
            dbg.intf[-1].msg("The program finished - quit or restart")
            dbg.core.processor.process_commands()
        except Mexcept.DebuggerQuit:
            break
        except Mexcept.DebuggerRestart:
            dbg.core.execution_status = 'Restart requested'
            if dbg.program_sys_argv:
                sys.argv = list(dbg.program_sys_argv)
                part1 = ('Restarting %s with arguments:' %
                         dbg.core.filename(mainpyfile))
                args  = ' '.join(dbg.program_sys_argv[1:])
                dbg.intf[-1].msg(Mmisc.wrapped_lines(part1, args,
                                                     dbg.settings['width']))
            else: break
        except SystemExit:
            # In most cases SystemExit does not warrant a post-mortem session.
            break
        except:
            # FIXME: Should be handled above without this mess
            exception_name = str(sys.exc_info()[0])
            if exception_name == str(Mexcept.DebuggerQuit):
                break
            elif exception_name == str(Mexcept.DebuggerRestart):
                dbg.core.execution_status = 'Restart requested'
                if dbg.program_sys_argv:
                    sys.argv = list(dbg.program_sys_argv)
                    part1 = ('Restarting %s with arguments:' %
                             dbg.core.filename(mainpyfile))
                    args  = ' '.join(dbg.program_sys_argv[1:])
                    dbg.intf[-1].msg(
                        Mmisc.wrapped_lines(part1, args,
                                            dbg.settings['width']))
                    pass
            else:
                raise
        pass

    # Restore old sys.argv
    sys.argv = orig_sys_argv
    return
Пример #17
0
def main(dbg=None, sys_argv=list(sys.argv)):
    """Routine which gets run if we were invoked directly"""

    # Save the original just for use in the restart that works via exec.
    orig_sys_argv = list(sys_argv)
    opts, dbg_opts, sys_argv  = Moptions.process_options(__title__,
                                                         __version__,
                                                         sys_argv)
    if opts.server:
        connection_opts={'IO': 'TCP', 'PORT': opts.port}
        intf = Mserver.ServerInterface(connection_opts=connection_opts)
        dbg_opts['interface'] = intf
        if 'FIFO' == intf.server_type:
            print('Starting FIFO server for process %s.' % os.getpid())
        elif 'TCP' == intf.server_type:
            print('Starting TCP server listening on port %s.' %
                  intf.inout.PORT)
            pass
    elif opts.client:
        Mclient.main(opts, sys_argv)
        return

    dbg_opts['orig_sys_argv'] = orig_sys_argv

    if dbg is None:
        dbg = Mdebugger.Debugger(dbg_opts)
        dbg.core.add_ignore(main)
        pass
    Moptions._postprocess_options(dbg, opts)

    # process_options has munged sys.argv to remove any options that
    # options that belong to this debugger. The original options to
    # invoke the debugger and script are in global sys_argv

    if len(sys_argv) == 0:
        # No program given to debug. Set to go into a command loop
        # anyway
        mainpyfile = None
    else:
        mainpyfile = sys_argv[0]  # Get script filename.
        if not os.path.isfile(mainpyfile):
            mainpyfile=Mclifns.whence_file(mainpyfile)
            is_readable = Mfile.readable(mainpyfile)
            if is_readable is None:
                print("%s: Python script file '%s' does not exist"
                      % (__title__, mainpyfile,), file=sys.stderr)
                sys.exit(1)
            elif not is_readable:
                print("%s: Can't read Python script file '%s'"
                      % (__title__, mainpyfile, ), file=sys.stderr)
                sys.exit(1)
                return

        if Mfile.is_compiled_py(mainpyfile):
            try:
                from uncompyle6 import uncompyle_file
            except ImportError:
                print("%s: Compiled python file '%s', but uncompyle6 not found"
                    % (__title__, mainpyfile), file=sys.stderr)
                sys.exit(1)

            short_name = os.path.basename(mainpyfile).strip('.pyc')
            fd = tempfile.NamedTemporaryFile(suffix='.py',
                                             prefix=short_name + "_",
                                             delete=False)
            try:
                uncompyle_file(mainpyfile, fd)
            except:
                print("%s: error uncompyling '%s'"
                      % (__title__, mainpyfile), file=sys.stderr)
                sys.exit(1)
            mainpyfile = fd.name
            fd.close()

        # If mainpyfile is an optimized Python script try to find and
        # use non-optimized alternative.
        mainpyfile_noopt = pyficache.pyc2py(mainpyfile)
        if mainpyfile != mainpyfile_noopt \
               and Mfile.readable(mainpyfile_noopt):
            print("%s: Compiled Python script given and we can't use that."
                  % __title__, file=sys.stderr)
            print("%s: Substituting non-compiled name: %s" % (
                __title__, mainpyfile_noopt,), file=sys.stderr)
            mainpyfile = mainpyfile_noopt
            pass

        # Replace trepan's dir with script's dir in front of
        # module search path.
        sys.path[0] = dbg.main_dirname = os.path.dirname(mainpyfile)

    # XXX If a signal has been received we continue in the loop, otherwise
    # the loop exits for some reason.
    dbg.sig_received = False

    # if not mainpyfile:
    #     print('For now, you need to specify a Python script name!')
    #     sys.exit(2)
    #     pass

    while True:

        # Run the debugged script over and over again until we get it
        # right.

        try:
            if dbg.program_sys_argv and mainpyfile:
                normal_termination = dbg.run_script(mainpyfile)
                if not normal_termination: break
            else:
                dbg.core.execution_status = 'No program'
                dbg.core.processor.process_commands()
                pass

            dbg.core.execution_status = 'Terminated'
            dbg.intf[-1].msg("The program finished - quit or restart")
            dbg.core.processor.process_commands()
        except Mexcept.DebuggerQuit:
            break
        except Mexcept.DebuggerRestart:
            dbg.core.execution_status = 'Restart requested'
            if dbg.program_sys_argv:
                sys.argv = list(dbg.program_sys_argv)
                part1 = ('Restarting %s with arguments:' %
                         dbg.core.filename(mainpyfile))
                args  = ' '.join(dbg.program_sys_argv[1:])
                dbg.intf[-1].msg(Mmisc.wrapped_lines(part1, args,
                                                     dbg.settings['width']))
            else: break
        except SystemExit:
            # In most cases SystemExit does not warrant a post-mortem session.
            break
        except:
            # FIXME: Should be handled above without this mess
            exception_name = str(sys.exc_info()[0])
            if exception_name == str(Mexcept.DebuggerQuit):
                break
            elif exception_name == str(Mexcept.DebuggerRestart):
                dbg.core.execution_status = 'Restart requested'
                if dbg.program_sys_argv:
                    sys.argv = list(dbg.program_sys_argv)
                    part1 = ('Restarting %s with arguments:' %
                             dbg.core.filename(mainpyfile))
                    args  = ' '.join(dbg.program_sys_argv[1:])
                    dbg.intf[-1].msg(
                        Mmisc.wrapped_lines(part1, args,
                                            dbg.settings['width']))
                    pass
            else:
                raise
        pass

    # Restore old sys.argv
    sys.argv = orig_sys_argv
    return
Пример #18
0
    def run(self, args):
        """Get file information"""
        if len(args) == 0:
            if not self.proc.curframe:
                self.errmsg("No frame - no default file.")
                return False
            filename = self.proc.curframe.f_code.co_filename
        else:
            filename = args[0]
            pass

        m = filename + " is"
        filename_cache = self.core.filename_cache
        if filename in filename_cache:
            m += " cached in debugger"
            if filename_cache[filename] != filename:
                m += " as:"
                m = Mmisc.wrapped_lines(m, filename_cache[filename] + ".", self.settings["width"])
            else:
                m += "."
                pass
            self.msg(m)
        else:
            matches = [file for file in file_list() if file.endswith(filename)]
            if len(matches) > 1:
                self.msg("Multiple files found ending filename string:")
                for match_file in matches:
                    self.msg("\t%s" % match_file)
                    pass
            elif len(matches) == 1:
                canonic_name = pyficache.unmap_file(matches[0])
                m += " matched debugger cache file:\n  " + canonic_name
                self.msg(m)
            else:
                self.msg(m + " not cached in debugger.")
            pass
        canonic_name = self.core.canonic(filename)
        self.msg(Mmisc.wrapped_lines("Canonic name:", canonic_name, self.settings["width"]))
        for name in (canonic_name, filename):
            if name in sys.modules:
                for key in [k for k, v in list(sys.modules.items()) if name == v]:
                    self.msg("module: %s", key)
                    pass
                pass
            pass
        for arg in args[1:]:
            processed_arg = False
            if arg in ["all", "size"]:
                if pyficache.size(canonic_name):
                    self.msg("File has %d lines." % pyficache.size(canonic_name))
                    pass
                processed_arg = True
                pass
            if arg in ["all", "sha1"]:
                self.msg("SHA1 is %s." % pyficache.sha1(canonic_name))
                processed_arg = True
                pass
            if arg in ["all", "brkpts"]:
                lines = pyficache.trace_line_numbers(canonic_name)
                if lines:
                    self.section("Possible breakpoint line numbers:")
                    fmt_lines = columnize.columnize(lines, ljust=False, arrange_vertical=False, lineprefix="  ")
                    self.msg(fmt_lines)
                    pass
                processed_arg = True
                pass
            if not processed_arg:
                self.errmsg("Don't understand sub-option %s." % arg)
                pass
            pass
        return
Пример #19
0
def set_break(
    cmd_obj,
    func,
    filename,
    lineno,
    condition,
    temporary,
    args,
    force=False,
    offset=None,
):
    if lineno is None and offset is None:
        part1 = (
            "I don't understand '%s' as a line number, offset, or function name,"
            % " ".join(args[1:]))
        msg = wrapped_lines(part1, "or file/module plus line number.",
                            cmd_obj.settings["width"])
        cmd_obj.errmsg(msg)
        return False
    if filename is None:
        filename = cmd_obj.proc.curframe.f_code.co_filename
        filename = cmd_obj.core.canonic(filename)
        pass
    if func is None:
        if lineno:
            line_info = code_line_info(filename, lineno)
            if not line_info:
                part1 = "File %s" % cmd_obj.core.filename(filename)
                msg = wrapped_lines(
                    part1,
                    "is not stoppable at line %d." % lineno,
                    cmd_obj.settings["width"],
                )
                cmd_obj.errmsg(msg)
                if force:
                    cmd_obj.msg(
                        "Breakpoint set although it may never be reached")
                else:
                    return False
        else:
            assert offset is not None
            lineno = code_offset_info(filename, offset)
            if lineno is None:
                part1 = "File %s" % cmd_obj.core.filename(filename)
                msg = wrapped_lines(
                    part1,
                    "has no line associated with offset %d." % offset,
                    cmd_obj.settings["width"],
                )
                cmd_obj.errmsg(msg)
                return False

        pass
    bp = cmd_obj.core.bpmgr.add_breakpoint(
        filename,
        lineno=lineno,
        offset=offset,
        temporary=temporary,
        condition=condition,
        func=func,
    )
    if func and inspect.isfunction(func):
        cmd_obj.msg("Breakpoint %d set on calling function %s()" %
                    (bp.number, func.__name__))
        part1 = "Currently this is line %d of file" % lineno
        msg = wrapped_lines(part1, cmd_obj.core.filename(filename),
                            cmd_obj.settings["width"])
        cmd_obj.msg(msg)
    else:
        part1 = "Breakpoint %d set at line %d of file" % (bp.number, lineno)
        msg = wrapped_lines(part1, cmd_obj.core.filename(filename),
                            cmd_obj.settings["width"])
        cmd_obj.msg(msg)
        if func:
            func_str = " of %s" % pretty_modfunc_name(func)
        else:
            func_str = ""
        if offset is not None and offset >= 0:
            cmd_obj.msg("Breakpoint is at offset %d%s " % (offset, func_str))
        pass
    return True
Пример #20
0
 def test_wrapped_msg(self):
     """Test misc.wrapped_lines()"""
     self.assertEqual('hi there', Mmisc.wrapped_lines('hi', 'there', 80))
     self.assertEqual('hi\n\tthere', Mmisc.wrapped_lines('hi', 'there', 5))
     return
Пример #21
0
def main(dbg=None, sys_argv=list(sys.argv)):
    """Routine which gets run if we were invoked directly"""

    # Save the original just for use in the restart that works via exec.
    orig_sys_argv = list(sys_argv)
    opts, dbg_opts, sys_argv = Moptions.process_options(
        __title__, __version__, sys_argv)
    if opts.server:
        connection_opts = {"IO": "TCP", "PORT": opts.port}
        intf = Mserver.ServerInterface(connection_opts=connection_opts)
        dbg_opts["interface"] = intf
        if "FIFO" == intf.server_type:
            print("Starting FIFO server for process %s." % os.getpid())
        elif "TCP" == intf.server_type:
            print("Starting TCP server listening on port %s." %
                  intf.inout.PORT)
            pass
    elif opts.client:
        Mclient.main(opts, sys_argv)
        return

    dbg_opts["orig_sys_argv"] = orig_sys_argv

    if dbg is None:
        dbg = Mdebugger.Debugger(dbg_opts)
        dbg.core.add_ignore(main)
        pass
    Moptions._postprocess_options(dbg, opts)

    # process_options has munged sys.argv to remove any options that
    # options that belong to this debugger. The original options to
    # invoke the debugger and script are in global sys_argv

    if len(sys_argv) == 0:
        # No program given to debug. Set to go into a command loop
        # anyway
        mainpyfile = None
    else:
        mainpyfile = sys_argv[0]  # Get script filename.
        if not osp.isfile(mainpyfile):
            mainpyfile = Mclifns.whence_file(mainpyfile)
            is_readable = Mfile.readable(mainpyfile)
            if is_readable is None:
                sys.stderr.write(
                    "%s: Python script file '%s' does not exist\n" %
                    (__title__, mainpyfile))
                sys.exit(1)
            elif not is_readable:
                sys.stderr.write("%s: Can't read Python script file '%s'\n" % (
                    __title__,
                    mainpyfile,
                ))
                sys.exit(1)
                return

        if Mfile.is_compiled_py(mainpyfile):
            try:
                from xdis import load_module
                from xdis_version import load_module, PYTHON_VERSION_TRIPLE, IS_PYPY, version_tuple_to_str

                (
                    python_version,
                    timestamp,
                    magic_int,
                    co,
                    is_pypy,
                    source_size,
                ) = load_module(mainpyfile, code_objects=None, fast_load=True)
                assert is_pypy == IS_PYPY
                assert (
                    python_version == PYTHON_VERSION_TRIPLE
                ), "bytecode is for version %s but we are version %s" % (
                    python_version,
                    version_tuple_to_str(),
                )
                # We should we check version magic_int

                py_file = co.co_filename
                if osp.isabs(py_file):
                    try_file = py_file
                else:
                    mainpydir = osp.dirname(mainpyfile)
                    dirnames = ([mainpydir] +
                                os.environ["PATH"].split(os.pathsep) + ["."])
                    try_file = Mclifns.whence_file(py_file, dirnames)

                if osp.isfile(try_file):
                    mainpyfile = try_file
                    pass
                else:
                    # Move onto the except branch
                    raise IOError(
                        "Python file name embedded in code %s not found" %
                        try_file)
            except:
                try:
                    from uncompyle6 import decompile_file
                except ImportError:
                    sys.stderr.write(
                        "%s: Compiled python file '%s', but uncompyle6 not found\n"
                        % (__title__, mainpyfile))
                    sys.exit(1)
                    return

                short_name = osp.basename(mainpyfile).strip(".pyc")
                fd = tempfile.NamedTemporaryFile(
                    suffix=".py",
                    prefix=short_name + "_",
                    dir=dbg.settings["tempdir"],
                    delete=False,
                )
                try:
                    decompile_file(mainpyfile, outstream=fd)
                    mainpyfile = fd.name
                    fd.close()
                except:
                    sys.stderr.write("%s: error uncompyling '%s'\n" %
                                     (__title__, mainpyfile))
                    sys.exit(1)
                pass

        # If mainpyfile is an optimized Python script try to find and
        # use non-optimized alternative.
        mainpyfile_noopt = pyficache.resolve_name_to_path(mainpyfile)
        if mainpyfile != mainpyfile_noopt \
               and Mfile.readable(mainpyfile_noopt):
            sys.stderr.write(
                "%s: Compiled Python script given and we can't use that.\n" %
                __title__)
            sys.stderr.write("%s: Substituting non-compiled name: %s\n" %
                             (__title__, mainpyfile_noopt))
            mainpyfile = mainpyfile_noopt
            pass

        # Replace trepan's dir with script's dir in front of
        # module search path.
        sys.path[0] = dbg.main_dirname = osp.dirname(mainpyfile)

    # XXX If a signal has been received we continue in the loop, otherwise
    # the loop exits for some reason.
    dbg.sig_received = False

    # if not mainpyfile:
    #     print('For now, you need to specify a Python script name!')
    #     sys.exit(2)
    #     pass

    while True:

        # Run the debugged script over and over again until we get it
        # right.

        try:
            if dbg.program_sys_argv and mainpyfile:
                normal_termination = dbg.run_script(mainpyfile)
                if not normal_termination:
                    break
            else:
                dbg.core.execution_status = "No program"
                dbg.core.processor.process_commands()
                pass

            dbg.core.execution_status = "Terminated"
            dbg.intf[-1].msg("The program finished - quit or restart")
            dbg.core.processor.process_commands()
        except Mexcept.DebuggerQuit:
            break
        except Mexcept.DebuggerRestart:
            dbg.core.execution_status = "Restart requested"
            if dbg.program_sys_argv:
                sys.argv = list(dbg.program_sys_argv)
                part1 = "Restarting %s with arguments:" % dbg.core.filename(
                    mainpyfile)
                args = " ".join(dbg.program_sys_argv[1:])
                dbg.intf[-1].msg(
                    Mmisc.wrapped_lines(part1, args, dbg.settings["width"]))
            else:
                break
        except SystemExit:
            # In most cases SystemExit does not warrant a post-mortem session.
            break
        except:
            # FIXME: Should be handled above without this mess
            exception_name = str(sys.exc_info()[0])
            if exception_name == str(Mexcept.DebuggerQuit):
                break
            elif exception_name == str(Mexcept.DebuggerRestart):
                dbg.core.execution_status = "Restart requested"
                if dbg.program_sys_argv:
                    sys.argv = list(dbg.program_sys_argv)
                    part1 = "Restarting %s with arguments:" % dbg.core.filename(
                        mainpyfile)
                    args = " ".join(dbg.program_sys_argv[1:])
                    dbg.intf[-1].msg(
                        Mmisc.wrapped_lines(part1, args,
                                            dbg.settings["width"]))
                    pass
            else:
                raise
        pass

    # Restore old sys.argv
    sys.argv = orig_sys_argv
    return
Пример #22
0
    def run(self, args):
        # It does not make much sense to repeat the last help
        # command. Also, given that 'help' uses PAGER, the you may
        # enter an extra CR which would rerun the (long) help command.
        self.proc.last_command = ''

        if len(args) > 1:
            cmd_name = args[1]
            if cmd_name == '*':
                self.section("List of all debugger commands:")
                m = self.columnize_commands(list(self.proc.commands.keys()))
                self.msg_nocr(m)
                return
            elif cmd_name == 'aliases':
                self.show_aliases()
                return
            elif cmd_name == 'macros':
                self.show_macros()
                return
            elif cmd_name == 'syntax':
                self.show_command_syntax(args)
                return
            elif cmd_name in list(categories.keys()):
                self.show_category(cmd_name, args[2:])
                return

            command_name = Mcmdproc.resolve_name(self.proc, cmd_name)
            if command_name:
                instance = self.proc.commands[command_name]
                if hasattr(instance, 'help'):
                    return instance.help(args)
                else:
                    doc = instance.__doc__ or instance.run.__doc__
                    doc = doc.rstrip('\n')
                    self.rst_msg(doc.rstrip("\n"))
                    aliases = [
                        key for key in self.proc.aliases
                        if command_name == self.proc.aliases[key]
                    ]
                    if len(aliases) > 0:
                        self.msg('')
                        msg = Mmisc.wrapped_lines('Aliases:',
                                                  ', '.join(aliases) + '.',
                                                  self.settings['width'])
                        self.msg(msg)
                        pass
                    pass
            else:
                cmds = [
                    cmd for cmd in list(self.proc.commands.keys())
                    if re.match('^' + cmd_name, cmd)
                ]
                if cmds is None:
                    self.errmsg("No commands found matching /^%s/. "
                                "Try \"help\"." % cmd_name)
                elif len(cmds) == 1:
                    self.msg("Pattern '%s' matches command %s..." % (
                        cmd_name,
                        cmds[0],
                    ))
                    args[1] = cmds[0]
                    self.run(args)
                else:
                    self.section("Command names matching /^%s/:" % cmd_name)
                    self.msg_nocr(self.columnize_commands(cmds))
                    pass
            return
        else:
            self.list_categories()
            pass

        return False
Пример #23
0
    def run(self, args):
        """Get file information"""
        if len(args) == 0:
            if not self.proc.curframe:
                self.errmsg("No frame - no default file.")
                return False
            filename = self.proc.curframe.f_code.co_filename
        else:
            filename = args[0]
            pass

        m = filename + ' is'
        filename_cache = self.core.filename_cache
        if filename in filename_cache:
            m += " cached in debugger"
            if filename_cache[filename] != filename:
                m += ' as:'
                m = Mmisc.wrapped_lines(m, filename_cache[filename] + '.',
                                        self.settings['width'])
            else:
                m += '.'
                pass
            self.msg(m)
        else:
            matches = [file for file in file_list() if file.endswith(filename)]
            if (len(matches) > 1):
                self.msg("Multiple files found ending filename string:")
                for match_file in matches:
                    self.msg("\t%s" % match_file)
                    pass
            elif len(matches) == 1:
                canonic_name = pyficache.unmap_file(matches[0])
                m += " matched debugger cache file:\n  " + canonic_name
                self.msg(m)
            else:
                self.msg(m + ' not cached in debugger.')
            pass
        canonic_name = self.core.canonic(filename)
        self.msg(
            Mmisc.wrapped_lines('Canonic name:', canonic_name,
                                self.settings['width']))
        for name in (canonic_name, filename):
            if name in sys.modules:
                for key in [
                        k for k, v in list(sys.modules.items()) if name == v
                ]:
                    self.msg("module: %s", key)
                    pass
                pass
            pass
        for arg in args[1:]:
            processed_arg = False
            if arg in ['all', 'size']:
                if pyficache.size(canonic_name):
                    self.msg("File has %d lines." %
                             pyficache.size(canonic_name))
                    pass
                processed_arg = True
                pass
            if arg in ['all', 'sha1']:
                self.msg("SHA1 is %s." % pyficache.sha1(canonic_name))
                processed_arg = True
                pass
            if arg in ['all', 'brkpts']:
                lines = pyficache.trace_line_numbers(canonic_name)
                if lines:
                    self.section("Possible breakpoint line numbers:")
                    fmt_lines = columnize.columnize(lines,
                                                    ljust=False,
                                                    arrange_vertical=False,
                                                    lineprefix='  ')
                    self.msg(fmt_lines)
                    pass
                processed_arg = True
                pass
            if not processed_arg:
                self.errmsg("Don't understand sub-option %s." % arg)
                pass
            pass
        return
Пример #24
0
    def run(self, args):
        # It does not make much sense to repeat the last help
        # command. Also, given that 'help' uses PAGER, the you may
        # enter an extra CR which would rerun the (long) help command.
        self.proc.last_command=''

        if len(args) > 1:
            cmd_name = args[1]
            if cmd_name == '*':
                self.section("List of all debugger commands:")
                m = self.columnize_commands(list(self.proc.commands.keys()))
                self.msg_nocr(m)
                return
            elif cmd_name == 'aliases':
                self.show_aliases()
                return
            elif cmd_name == 'macros':
                self.show_macros()
                return
            elif cmd_name == 'syntax':
                self.show_command_syntax(args)
                return
            elif cmd_name in list(categories.keys()):
                self.show_category(cmd_name, args[2:])
                return

            command_name = Mcmdproc.resolve_name(self.proc, cmd_name)
            if command_name:
                instance = self.proc.commands[command_name]
                if hasattr(instance, 'help'):
                    return instance.help(args)
                else:
                    doc = instance.__doc__ or instance.run.__doc__
                    doc = doc.rstrip('\n')
                    self.rst_msg(doc.rstrip("\n"))
                    aliases = [key for key in self.proc.aliases
                               if command_name == self.proc.aliases[key]]
                    if len(aliases) > 0:
                        self.msg('')
                        msg = Mmisc.wrapped_lines('Aliases:',
                                                  ', '.join(aliases) + '.',
                                                  self.settings['width'])
                        self.msg(msg)
                        pass
                    pass
            else:
                cmds = [cmd for cmd in list(self.proc.commands.keys())
                        if re.match('^' + cmd_name, cmd) ]
                if cmds is None:
                    self.errmsg("No commands found matching /^%s/. "
                                "Try \"help\"." % cmd_name)
                elif len(cmds) == 1:
                    self.msg("Pattern '%s' matches command %s..." %
                             (cmd_name, cmds[0],))
                    args[1] = cmds[0]
                    self.run(args)
                else:
                    self.section("Command names matching /^%s/:" % cmd_name)
                    self.msg_nocr(self.columnize_commands(cmds))
                    pass
            return
        else:
            self.list_categories()
            pass

        return False
Пример #25
0
def main(dbg=None, sys_argv=list(sys.argv)):
    """Routine which gets run if we were invoked directly"""
    global __title__

    # Save the original just for use in the restart that works via exec.
    orig_sys_argv = list(sys_argv)
    opts, dbg_opts, sys_argv = process_options(__title__, __version__,
                                               sys_argv)
    dbg_opts['orig_sys_argv'] = sys_argv
    dbg_opts['interface'] = Mbullwinkle.BWInterface()
    dbg_opts['processor'] = 'bullwinkle'

    if dbg is None:
        dbg = Mdebugger.Debugger(dbg_opts)
        dbg.core.add_ignore(main)
        pass
    _postprocess_options(dbg, opts)

    # process_options has munged sys.argv to remove any options that
    # options that belong to this debugger. The original options to
    # invoke the debugger and script are in global sys_argv
    if len(sys_argv) == 0:
        # No program given to debug. Set to go into a command loop
        # anyway
        mainpyfile = None
    else:
        mainpyfile = sys_argv[0]  # Get script filename.
        if not os.path.isfile(mainpyfile):
            mainpyfile = Mclifns.whence_file(mainpyfile)
            is_readable = Mfile.readable(mainpyfile)
            if is_readable is None:
                print("%s: Python script file '%s' does not exist" % (
                    __title__,
                    mainpyfile,
                ))
                sys.exit(1)
            elif not is_readable:
                print("%s: Can't read Python script file '%s'" % (
                    __title__,
                    mainpyfile,
                ))
                sys.exit(1)
                return

        # If mainpyfile is an optimized Python script try to find and
        # use non-optimized alternative.
        mainpyfile_noopt = pyficache.pyc2py(mainpyfile)
        if mainpyfile != mainpyfile_noopt \
               and Mfile.readable(mainpyfile_noopt):
            print("%s: Compiled Python script given and we can't use that." %
                  __title__)
            print("%s: Substituting non-compiled name: %s" % (
                __title__,
                mainpyfile_noopt,
            ))
            mainpyfile = mainpyfile_noopt
            pass

        # Replace trepan's dir with script's dir in front of
        # module search path.
        sys.path[0] = dbg.main_dirname = os.path.dirname(mainpyfile)

    # XXX If a signal has been received we continue in the loop, otherwise
    # the loop exits for some reason.
    dbg.sig_received = False

    # if not mainpyfile:
    #     print('For now, you need to specify a Python script name!')
    #     sys.exit(2)
    #     pass

    while True:

        # Run the debugged script over and over again until we get it
        # right.

        try:
            if dbg.program_sys_argv and mainpyfile:
                normal_termination = dbg.run_script(mainpyfile)
                if not normal_termination: break
            else:
                dbg.core.execution_status = 'No program'
                dbg.core.processor.process_commands()
                pass

            dbg.core.execution_status = 'Terminated'
            dbg.intf[-1].msg("The program finished - quit or restart")
            dbg.core.processor.process_commands()
        except Mexcept.DebuggerQuit:
            break
        except Mexcept.DebuggerRestart:
            dbg.core.execution_status = 'Restart requested'
            if dbg.program_sys_argv:
                sys.argv = list(dbg.program_sys_argv)
                part1 = ('Restarting %s with arguments:' %
                         dbg.core.filename(mainpyfile))
                args = ' '.join(dbg.program_sys_argv[1:])
                dbg.intf[-1].msg(
                    Mmisc.wrapped_lines(part1, args, dbg.settings['width']))
            else:
                break
        except SystemExit:
            # In most cases SystemExit does not warrant a post-mortem session.
            break
        pass

    # Restore old sys.argv
    sys.argv = orig_sys_argv
    return
Пример #26
0
    def run(self, args):
        """**info files** [*filename* [**all** | **brkpts** | **lines** | **sha1** | **size**]]

        Show information about the current file. If no filename is
        given and the program is running then the current file associated
        with the current stack entry is used. Sub options which can be
        shown about a file are:

        * **brkpts** Line numbers where there are statement boundaries. These lines can be used in breakpoint commands.

        * **sha1**	A SHA1 hash of the source text.

        The following may be useful in comparing source code.

        * **size**	The number of lines in the file.

        * **all** All of the above information.
        """
        if len(args) == 0:
            if not self.proc.curframe:
                self.errmsg("No frame - no default file.")
                return False
            filename = self.proc.curframe.f_code.co_filename
        else:
            filename = args[0]
            pass

        m = filename + " is"
        filename_cache = self.core.filename_cache
        if filename in filename_cache:
            m += " cached in debugger"
            if filename_cache[filename] != filename:
                m += " as:"
                m = Mmisc.wrapped_lines(m, filename_cache[filename] + ".",
                                        self.settings["width"])
            else:
                m += "."
                pass
            self.msg(m)
        else:
            matches = [file for file in file_list() if file.endswith(filename)]
            if len(matches) > 1:
                self.msg("Multiple files found ending filename string:")
                for match_file in matches:
                    self.msg("\t%s" % match_file)
                    pass
            elif len(matches) == 1:
                canonic_name = pyficache.unmap_file(matches[0])
                m += " matched debugger cache file:\n  " + canonic_name
                self.msg(m)
            else:
                self.msg(m + " not cached in debugger.")
            pass
        canonic_name = self.core.canonic(filename)
        self.msg(
            Mmisc.wrapped_lines("Canonic name:", canonic_name,
                                self.settings["width"]))
        for name in (canonic_name, filename):
            if name in sys.modules:
                for key in [
                        k for k, v in list(sys.modules.items()) if name == v
                ]:
                    self.msg("module: %s", key)
                    pass
                pass
            pass
        for arg in args[1:]:
            processed_arg = False
            if arg in ["all", "size"]:
                if pyficache.size(canonic_name):
                    self.msg("File has %d lines." %
                             pyficache.size(canonic_name))
                    pass
                processed_arg = True
                pass
            if arg in ["all", "sha1"]:
                self.msg("SHA1 is %s." % pyficache.sha1(canonic_name))
                processed_arg = True
                pass
            if arg in ["all", "brkpts"]:
                lines = pyficache.trace_line_numbers(canonic_name)
                if lines:
                    self.section("Possible breakpoint line numbers:")
                    fmt_lines = columnize.columnize(
                        list(lines),
                        ljust=False,
                        arrange_vertical=False,
                        lineprefix="  ",
                    )
                    self.msg(fmt_lines)
                    pass
                processed_arg = True
                pass
            if not processed_arg:
                self.errmsg("Don't understand sub-option %s." % arg)
                pass
            pass
        return
Пример #27
0
def main(dbg=None, sys_argv=list(sys.argv)):
    """Routine which gets run if we were invoked directly"""
    global __title__

    # Save the original just for use in the restart that works via exec.
    orig_sys_argv = list(sys_argv)
    opts, dbg_opts, sys_argv  = process_options(__title__, __version__,
                                                sys_argv)
    dbg_opts['orig_sys_argv'] = sys_argv
    dbg_opts['interface']     = Mbullwinkle.BWInterface()
    dbg_opts['processor']     = 'bullwinkle'

    if dbg is None:
        dbg = Mdebugger.Debugger(dbg_opts)
        dbg.core.add_ignore(main)
        pass
    _postprocess_options(dbg, opts)

    # process_options has munged sys.argv to remove any options that
    # options that belong to this debugger. The original options to
    # invoke the debugger and script are in global sys_argv
    if len(sys_argv) == 0:
        # No program given to debug. Set to go into a command loop
        # anyway
        mainpyfile = None
    else:
        mainpyfile = sys_argv[0]  # Get script filename.
        if not os.path.isfile(mainpyfile):
            mainpyfile=Mclifns.whence_file(mainpyfile)
            is_readable = Mfile.readable(mainpyfile)
            if is_readable is None:
                print("%s: Python script file '%s' does not exist"
                      % (__title__, mainpyfile,))
                sys.exit(1)
            elif not is_readable:
                print("%s: Can't read Python script file '%s'"
                      % (__title__, mainpyfile,))
                sys.exit(1)
                return

        # If mainpyfile is an optimized Python script try to find and
        # use non-optimized alternative.
        mainpyfile_noopt = pyficache.pyc2py(mainpyfile)
        if mainpyfile != mainpyfile_noopt \
               and Mfile.readable(mainpyfile_noopt):
            print("%s: Compiled Python script given and we can't use that."
                  % __title__)
            print("%s: Substituting non-compiled name: %s" % (
                __title__, mainpyfile_noopt,))
            mainpyfile = mainpyfile_noopt
            pass

        # Replace trepan's dir with script's dir in front of
        # module search path.
        sys.path[0] = dbg.main_dirname = os.path.dirname(mainpyfile)

    # XXX If a signal has been received we continue in the loop, otherwise
    # the loop exits for some reason.
    dbg.sig_received = False

    # if not mainpyfile:
    #     print('For now, you need to specify a Python script name!')
    #     sys.exit(2)
    #     pass

    while True:

        # Run the debugged script over and over again until we get it
        # right.

        try:
            if dbg.program_sys_argv and mainpyfile:
                normal_termination = dbg.run_script(mainpyfile)
                if not normal_termination: break
            else:
                dbg.core.execution_status = 'No program'
                dbg.core.processor.process_commands()
                pass

            dbg.core.execution_status = 'Terminated'
            dbg.intf[-1].msg("The program finished - quit or restart")
            dbg.core.processor.process_commands()
        except Mexcept.DebuggerQuit:
            break
        except Mexcept.DebuggerRestart:
            dbg.core.execution_status = 'Restart requested'
            if dbg.program_sys_argv:
                sys.argv = list(dbg.program_sys_argv)
                part1 = ('Restarting %s with arguments:' %
                         dbg.core.filename(mainpyfile))
                args  = ' '.join(dbg.program_sys_argv[1:])
                dbg.intf[-1].msg(Mmisc.wrapped_lines(part1, args,
                                                     dbg.settings['width']))
            else: break
        except SystemExit:
            # In most cases SystemExit does not warrant a post-mortem session.
            break
        pass

    # Restore old sys.argv
    sys.argv = orig_sys_argv
    return
Пример #28
0
def main(dbg=None, sys_argv=list(sys.argv)):
    """Routine which gets run if we were invoked directly"""
    global __title__

    # Save the original just for use in the restart that works via exec.
    orig_sys_argv = list(sys_argv)
    opts, dbg_opts, sys_argv = Moptions.process_options(
        __title__, VERSION, sys_argv)

    if opts.server is not None:
        if opts.server == 'tcp':
            connection_opts = {'IO': 'TCP', 'PORT': opts.port}
        else:
            connection_opts = {'IO': 'FIFO'}
        intf = Mserver.ServerInterface(connection_opts=connection_opts)
        dbg_opts['interface'] = intf
        if 'FIFO' == intf.server_type:
            print('Starting FIFO server for process %s.' % os.getpid())
        elif 'TCP' == intf.server_type:
            print('Starting TCP server listening on port %s.' %
                  intf.inout.PORT)
            pass
    elif opts.client:
        Mclient.main(opts, sys_argv)
        return

    dbg_opts['orig_sys_argv'] = orig_sys_argv

    if dbg is None:
        dbg = Mdebugger.Trepan(dbg_opts)
        dbg.core.add_ignore(main)
        pass
    Moptions._postprocess_options(dbg, opts)

    # process_options has munged sys.argv to remove any options that
    # options that belong to this debugger. The original options to
    # invoke the debugger and script are in global sys_argv

    if len(sys_argv) == 0:
        # No program given to debug. Set to go into a command loop
        # anyway
        mainpyfile = None
    else:
        mainpyfile = sys_argv[0]  # Get script filename.
        if not osp.isfile(mainpyfile):
            mainpyfile = Mclifns.whence_file(mainpyfile)
            is_readable = Mfile.readable(mainpyfile)
            if is_readable is None:
                print("%s: Python script file '%s' does not exist" % (
                    __title__,
                    mainpyfile,
                ))
                sys.exit(1)
            elif not is_readable:
                print("%s: Can't read Python script file '%s'" % (
                    __title__,
                    mainpyfile,
                ))
                sys.exit(1)
                return

        if Mfile.is_compiled_py(mainpyfile):
            try:
                from xdis import load_module, PYTHON_VERSION, IS_PYPY
                (python_version, timestamp, magic_int, co, is_pypy,
                 source_size) = load_module(mainpyfile,
                                            code_objects=None,
                                            fast_load=True)
                assert is_pypy == IS_PYPY
                assert python_version == PYTHON_VERSION, \
                    "bytecode is for version %s but we are version %s" % (
                        python_version, PYTHON_VERSION)
                # We should we check version magic_int

                py_file = co.co_filename
                if osp.isabs(py_file):
                    try_file = py_file
                else:
                    mainpydir = osp.dirname(mainpyfile)
                    tag = sys.implementation.cache_tag
                    dirnames = [
                        osp.join(mainpydir, tag), mainpydir
                    ] + os.environ['PATH'].split(osp.pathsep) + ['.']
                    try_file = Mclifns.whence_file(py_file, dirnames)

                if osp.isfile(try_file):
                    mainpyfile = try_file
                    pass
                else:
                    # Move onto the except branch
                    raise IOError(
                        "Python file name embedded in code %s not found" %
                        try_file)
            except IOError:
                try:
                    from uncompyle6 import decompile_file
                except ImportError:
                    print(
                        "%s: Compiled python file '%s', but uncompyle6 not found"
                        % (__title__, mainpyfile),
                        file=sys.stderr)
                    sys.exit(1)
                    return

                short_name = osp.basename(mainpyfile).strip('.pyc')
                fd = tempfile.NamedTemporaryFile(suffix='.py',
                                                 prefix=short_name + "_",
                                                 delete=False)
                old_write = fd.file.write

                def write_wrapper(*args, **kwargs):
                    if isinstance(args[0], str):
                        new_args = list(args)
                        new_args[0] = args[0].encode('utf-8')
                        old_write(*new_args, **kwargs)
                    else:
                        old_write(*args, **kwargs)

                fd.file.write = write_wrapper

                # from io import StringIO
                # linemap_io = StringIO()
                try:
                    decompile_file(mainpyfile, fd.file, mapstream=fd)
                except:
                    print("%s: error decompiling '%s'" %
                          (__title__, mainpyfile),
                          file=sys.stderr)
                    sys.exit(1)
                    return

                # # Get the line associations between the original and
                # # decompiled program
                # mapline = linemap_io.getvalue()
                # fd.write(mapline + "\n\n")
                # linemap = eval(mapline[3:])
                mainpyfile = fd.name
                fd.close()

                # Since we are actually running the recreated source,
                # there is little no need to remap line numbers.
                # The mapping is given at the end of the file.
                # However we should consider adding this information
                # and original file name.

                print(
                    "%s: couldn't find Python source so we recreated it at '%s'"
                    % (__title__, mainpyfile),
                    file=sys.stderr)

                pass

        # If mainpyfile is an optimized Python script try to find and
        # use non-optimized alternative.
        mainpyfile_noopt = pyficache.pyc2py(mainpyfile)
        if mainpyfile != mainpyfile_noopt \
               and Mfile.readable(mainpyfile_noopt):
            print("%s: Compiled Python script given and we can't use that." %
                  __title__)
            print("%s: Substituting non-compiled name: %s" % (
                __title__,
                mainpyfile_noopt,
            ))
            mainpyfile = mainpyfile_noopt
            pass

        # Replace trepan's dir with script's dir in front of
        # module search path.
        sys.path[0] = dbg.main_dirname = osp.dirname(mainpyfile)

    # XXX If a signal has been received we continue in the loop, otherwise
    # the loop exits for some reason.
    dbg.sig_received = False

    # if not mainpyfile:
    #     print('For now, you need to specify a Python script name!')
    #     sys.exit(2)
    #     pass

    while True:

        # Run the debugged script over and over again until we get it
        # right.

        try:
            if dbg.program_sys_argv and mainpyfile:
                normal_termination = dbg.run_script(mainpyfile)
                if not normal_termination: break
            else:
                dbg.core.execution_status = 'No program'
                dbg.core.processor.process_commands()
                pass

            dbg.core.execution_status = 'Terminated'
            dbg.intf[-1].msg("The program finished - quit or restart")
            dbg.core.processor.process_commands()
        except Mexcept.DebuggerQuit:
            break
        except Mexcept.DebuggerRestart:
            dbg.core.execution_status = 'Restart requested'
            if dbg.program_sys_argv:
                sys.argv = list(dbg.program_sys_argv)
                part1 = ('Restarting %s with arguments:' %
                         dbg.core.filename(mainpyfile))
                args = ' '.join(dbg.program_sys_argv[1:])
                dbg.intf[-1].msg(
                    Mmisc.wrapped_lines(part1, args, dbg.settings['width']))
            else:
                break
        except SystemExit:
            # In most cases SystemExit does not warrant a post-mortem session.
            break
        pass

    # Restore old sys.argv
    sys.argv = orig_sys_argv
    return