Пример #1
0
def retrieve_post_mortem_stack_infos(traceback_):
    """Retrieve post mortem all local and global
    variables of given traceback"""

    base_debugger = Bdb()
    stack, i = base_debugger.get_stack(None, traceback_)

    # Get global and local vals
    locals_ = stack[i][0].f_locals
    globals_ = stack[i][0].f_globals
    return locals_, globals_
Пример #2
0
class ManagedDebugger(object):
    """ Managed Python Debugger """

    _wait_stack_height = 0
    _done = False
    _excep_logged = False
    _script_lines = []

    def __init__(self, action_handler, **kwargs):
        super(ManagedDebugger, self).__init__(**kwargs)
        self._bdb = Bdb()
        self._sandbox = Sandbox()
        self._handler = action_handler

        self._bdb.user_call = self._bdb_call
        self._bdb.user_line = self._bdb_line
        self._bdb.user_return = self._bdb_return
        self._bdb.user_exception = self._bdb_exception

    def _initialize(self):
        self._done = False
        self._excep_logged = False

        self._wait_stack_height = 0

    # bdb Callbacks
    def _bdb_call(self, frame, args):
        if self._done:
            return  # Execution is stopped

        if frame.f_code.co_filename != "<string>" or frame.f_lineno <= 0:
            self._wait_stack_height += 1
            return

        if self._wait_stack_height:
            self._wait_stack_height += 1
            return

        if not self._bdb.stop_here(frame):
            return

        script_line = self._get_script_line(frame.f_code.co_firstlineno)
        if contains_class_defination(script_line):
            self._wait_stack_height = 1
            return

        args = self._extract_passed_arguments(frame)
        self.trigger(DebuggerEvent.EnterBlock, frame=frame, arguments=args)

    def _extract_passed_arguments(self, frame):
        function = frame.f_globals[frame.f_code.co_name]
        arg_specs = inspect.getargspec(function)

        args = {arg: frame.f_locals[arg] for arg in arg_specs.args}

        if arg_specs.varargs:
            args[arg_specs.varargs] = frame.f_locals[arg_specs.varargs]

        if arg_specs.keywords:
            args[arg_specs.keywords] = frame.f_locals[arg_specs.keywords]

        return args

    def _bdb_line(self, frame):
        if self._done or self._wait_stack_height:
            return

        self._excep_logged = False
        self.trigger(DebuggerEvent.StepLine, frame=frame)

    def _bdb_return(self, frame, value):
        if self._done:
            return

        if self._wait_stack_height:
            self._wait_stack_height -= 1
        elif frame.f_code.co_filename == "<string>":
            self.trigger(DebuggerEvent.ExitBlock,
                         frame=frame,
                         return_value=value)

    def _bdb_exception(self, frame, info):
        if self._done or self._wait_stack_height:
            return

        self._excep_logged = True
        ex_type, value, tb = info

        self.trigger(DebuggerEvent.Exception,
                     frame=frame,
                     ex_type=ex_type,
                     value=value,
                     traceback=tb)

    def trigger(self, event, *args, **kwargs):
        return self._handler(event, *args, **kwargs)

    def _get_script_line(self, n):
        return self.script_lines[n - 1]

    def get_stack(self, frame, tb):
        return self._bdb.get_stack(frame, tb)

    @property
    def stdout(self):
        return self._sandbox.stdout

    def run(self, script, input_queue=None):
        self._initialize()

        try:
            self.script_lines = script.splitlines()
            self._sandbox.run(script, input_queue, runner=self._bdb.run)
        except SyntaxError as ex:
            self.trigger(DebuggerEvent.SyntaxError, exception=ex)
        except:
            if not self._excep_logged:
                logger.exception(
                    "Internal Error in Debugger\n"
                    "Script:\n%s\n"
                    "Input Queue:%s", script, input_queue)
                ex_type, value, tb = sys.exc_info()
                self.trigger(DebuggerEvent.SystemError,
                             type=ex_type,
                             value=value,
                             traceback=tb)
        finally:
            self._done = True
Пример #3
0
class ManagedDebugger(object):
    """ Managed Python Debugger """

    _wait_stack_height = 0
    _done = False
    _excep_logged = False
    _script_lines = []

    def __init__(self, action_handler, **kwargs):
        super(ManagedDebugger, self).__init__(**kwargs)
        self._bdb = Bdb()
        self._sandbox = Sandbox()
        self._handler = action_handler

        self._bdb.user_call = self._bdb_call
        self._bdb.user_line = self._bdb_line
        self._bdb.user_return = self._bdb_return
        self._bdb.user_exception = self._bdb_exception

    def _initialize(self):
        self._done = False
        self._excep_logged = False

        self._wait_stack_height = 0

    # bdb Callbacks
    def _bdb_call(self, frame, args):
        if self._done:
            return  # Execution is stopped

        if frame.f_code.co_filename != "<string>" or frame.f_lineno <= 0:
            self._wait_stack_height += 1
            return

        if self._wait_stack_height:
            self._wait_stack_height += 1
            return

        if not self._bdb.stop_here(frame):
            return

        script_line = self._get_script_line(frame.f_code.co_firstlineno)
        if contains_class_defination(script_line):
            self._wait_stack_height = 1
            return

        args = self._extract_passed_arguments(frame)
        self.trigger(DebuggerEvent.EnterBlock, frame=frame, arguments=args)

    def _extract_passed_arguments(self, frame):
        function = frame.f_globals[frame.f_code.co_name]
        arg_specs = inspect.getargspec(function)

        args = {
            arg: frame.f_locals[arg]
            for arg in arg_specs.args
        }

        if arg_specs.varargs:
            args[arg_specs.varargs] = frame.f_locals[arg_specs.varargs]

        if arg_specs.keywords:
            args[arg_specs.keywords] = frame.f_locals[arg_specs.keywords]

        return args

    def _bdb_line(self, frame):
        if self._done or self._wait_stack_height:
            return

        self._excep_logged = False
        self.trigger(DebuggerEvent.StepLine, frame=frame)

    def _bdb_return(self, frame, value):
        if self._done:
            return

        if self._wait_stack_height:
            self._wait_stack_height -= 1
        elif frame.f_code.co_filename == "<string>":
            self.trigger(DebuggerEvent.ExitBlock, frame=frame, return_value=value)

    def _bdb_exception(self, frame, info):
        if self._done or self._wait_stack_height:
            return

        self._excep_logged = True
        ex_type, value, tb = info

        self.trigger(DebuggerEvent.Exception, frame=frame, ex_type=ex_type,
                     value=value, traceback=tb)

    def trigger(self, event, *args, **kwargs):
        return self._handler(event, *args, **kwargs)

    def _get_script_line(self, n):
        return self.script_lines[n - 1]

    def get_stack(self, frame, tb):
        return self._bdb.get_stack(frame, tb)

    @property
    def stdout(self):
        return self._sandbox.stdout

    def run(self, script, input_queue=None):
        self._initialize()

        try:
            self.script_lines = script.splitlines()
            self._sandbox.run(script, input_queue, runner=self._bdb.run)
        except SyntaxError as ex:
            self.trigger(DebuggerEvent.SyntaxError, exception=ex)
        except:
            if not self._excep_logged:
                logger.exception(
                    "Internal Error in Debugger\n"
                    "Script:\n%s\n"
                    "Input Queue:%s",
                    script, input_queue
                )
                ex_type, value, tb = sys.exc_info()
                self.trigger(DebuggerEvent.SystemError, type=ex_type,
                             value=value, traceback=tb)
        finally:
            self._done = True