Esempio n. 1
0
    def test_trace_filtering(self):
        """Test that trace hook is triggering event callbacks with filtering."""
        global ignore_filter
        ignore_filter = tracefilter.TraceFilter()
        tracer.clear_hooks_and_stop()
        self.assertEqual(
            1,
            tracer.add_hook(my_trace_dispatch, {
                'start': True,
                'event_set': frozenset(('call', ))
            }))

        def foo():
            pass

        foo()
        tracer.stop()
        global trace_lines
        import pprint
        #         for entry in trace_lines:
        #             print entry.event, entry.filename, entry.lineno, entry.name
        self.assertTrue(
            len(trace_lines) >= 2, 'Should have captured some trace output')
        for i, right in [(-1, (
                'call',
                'stop',
        )), (-2, (
                'call',
                'foo',
        ))]:
            self.assertEqual(right, (
                trace_lines[i].event,
                trace_lines[i].name,
            ))
        return
Esempio n. 2
0
 def __init__(self, debugger):
     self.debugger = debugger
     self.execution_status = 'Pre-execution'
     self.filename_cache = {}
     self.ignore_filter = tracefilter.TraceFilter([])
     self.bpmgr = breakpoint.BreakpointManager()
     self.processor = MockProcessor(self)
     self.step_ignore = -1
     self.stop_frame = None
     self.last_lineno = None
     self.last_filename = None
     self.different_line = None
     return
Esempio n. 3
0
class Debugger:

    # The following functions have to be defined before
    # DEFAULT_INIT_OPTS which includes references to these.

    # FIXME DRY run, run_exec, run_eval.

    def run(self, cmd, start_opts=None, globals_=None, locals_=None):
        """ Run debugger on string `cmd' using builtin function eval
        and if that builtin exec.  Arguments `globals_' and `locals_'
        are the dictionaries to use for local and global variables. By
        default, the value of globals is globals(), the current global
        variables. If `locals_' is not given, it becomes a copy of
        `globals_'.

        Debugger.core.start settings are passed via optional
        dictionary `start_opts'. Overall debugger settings are in
        Debugger.settings which changed after an instance is created
        . Also see `run_eval' if what you want to run is an
        run_eval'able expression have that result returned and
        `run_call' if you want to debug function run_call.
        """
        if globals_ is None:
            globals_ = globals()
        if locals_ is None:
            locals_ = globals_
        if not isinstance(cmd, types.CodeType):
            self.eval_string = cmd
            cmd = cmd+'\n'
            pass
        retval = None
        self.core.start(start_opts)
        try:
            retval = eval(cmd, globals_, locals_)
        except SyntaxError:
            try:
                exec(cmd, globals_, locals_)
            except DebuggerQuit:
                pass
            except DebuggerQuit:
                pass
            pass
        except DebuggerQuit:
            pass
        self.core.stop()
        return retval

    def run_exec(self, cmd, start_opts=None, globals_=None, locals_=None):
        """ Run debugger on string `cmd' which will executed via the
        builtin function exec. Arguments `globals_' and `locals_' are
        the dictionaries to use for local and global variables. By
        default, the value of globals is globals(), the current global
        variables. If `locals_' is not given, it becomes a copy of
        `globals_'.

        Debugger.core.start settings are passed via optional
        dictionary `start_opts'. Overall debugger settings are in
        Debugger.settings which changed after an instance is created
        . Also see `run_eval' if what you want to run is an
        run_eval'able expression have that result returned and
        `run_call' if you want to debug function run_call.
        """
        if globals_ is None:
            globals_ = globals()
        if locals_ is None:
            locals_ = globals_
        if not isinstance(cmd, types.CodeType):
            cmd = cmd+'\n'
            pass
        self.core.start(start_opts)
        try:
            exec(cmd, globals_, locals_)
        except DebuggerQuit:
            pass
        self.core.stop()
        return

    def run_call(self, func, start_opts=None, *args, **kwds):
        """ Run debugger on function call: `func(*args, **kwds)'

        See also `run_eval' if what you want to run is an eval'able
        expression have that result returned and `run' if you want to
        debug a statment via exec.
        """
        res = None
        self.core.start(opts=start_opts)
        try:
            res = func(*args, **kwds)
        except DebuggerQuit:
            pass
        self.core.stop()
        return res

    def run_eval(self, expr, start_opts=None, globals_=None, locals_=None):
        """ Run debugger on string `expr' which will executed via the
        built-in Python function: eval; `globals_' and `locals_' are
        the dictionaries to use for local and global variables. If
        `globals' is not given, __main__.__dict__ (the current global
        variables) is used. If `locals_' is not given, it becomes a
        copy of `globals_'.

        See also `run_call' if what you to debug a function call and
        `run' if you want to debug general Python statements.
        """
        if globals_ is None:
            globals_ = globals()
        if locals_ is None:
            locals_ = globals_
        if not isinstance(expr, types.CodeType):
            self.eval_string = expr
            expr = expr+'\n'
            pass
        retval = None
        self.core.start(start_opts)
        try:
            retval = eval(expr, globals_, locals_)
        except DebuggerQuit:
            pass
        finally:
            pyficache.remove_remap_file('<string>')
            self.core.stop()
        return retval

    def run_script(self, filename, start_opts=None, globals_=None,
                   locals_=None):
        """ Run debugger on Python script `filename'. The script may
        inspect sys.argv for command arguments. `globals_' and
        `locals_' are the dictionaries to use for local and global
        variables. If `globals' is not given, globals() (the current
        global variables) is used. If `locals_' is not given, it
        becomes a copy of `globals_'.

        True is returned if the program terminated normally and False
        if the debugger initiated a quit or the program did not normally
        terminate.

        See also `run_call' if what you to debug a function call,
        `run_eval' if you want to debug an expression, and `run' if you
        want to debug general Python statements not inside a file.
        """
        self.mainpyfile = self.core.canonic(filename)

        # Start with fresh empty copy of globals and locals and tell the script
        # that it's being run as __main__ to avoid scripts being able to access
        # the debugger namespace.
        if globals_ is None:
            import __main__  # NOQA
            globals_ = {"__name__" : "__main__",
                       "__file__" : self.mainpyfile,
                       "__builtins__" : __builtins__
                        }
        if locals_ is None:
            locals_ = globals_
        self.core.start(start_opts)
        retval = False
        self.core.execution_status = 'Running'
        try:
            exec(compile(open(self.mainpyfile).read(), self.mainpyfile,
                         'exec'), globals_, locals_)
            retval = True
        except SyntaxError:
            print(sys.exc_info()[1])
            retval = False
            pass
        except IOError:
            print(sys.exc_info()[1])
        except DebuggerQuit:
            retval = False
            pass
        except DebuggerRestart:
            self.core.execution_status = 'Restart requested'
            raise DebuggerRestart
        self.core.stop(options={'remove': True})
        return retval

    def restart_argv(self):
        '''Return an array that would be execv-ed  to restart the program'''
        return self.orig_sys_argv or self.program_sys_argv

    # Note: has to come after functions listed in ignore_filter.
    DEFAULT_INIT_OPTS = {
        # What routines will we not trace into?
        'ignore_filter': tracefilter.TraceFilter(
            [tracer.start, tracer.stop,
             run_eval, run_call, run_eval, run_script]),

        # sys.argv when not None contains sys.argv *before* debugger
        # command processing. So sys.argv contains debugger options as
        # well as debugged-program options. These options are used to
        # do a "hard" or execv() restart.

        # program_sys_argv is set by option save_sys_argv and contains
        # sys.argv that we see now which may have debugger options
        # stripped, or it may be that we were not called from a
        # debugger front end but from inside the running
        # program. These options are suitable for a "soft" or
        # exception-handling DebuggerRestart kind of restart.
        'orig_sys_argv' : None,
        'save_sys_argv' : True,

        # How is I/O for this debugger handled?
        'activate'    : False,
        'interface'   : None,
        'input'       : None,
        'output'      : None,
        'processor'   : None,

        # Setting contains lots of debugger settings - a whole file
        # full of them!
        'settings'    : Mdefault.DEBUGGER_SETTINGS,

        'start_opts'  : Mdefault.START_OPTS,
        'step_ignore' : 0,

        'from_ipython' : False
        }

    def __init__(self, opts=None):
        """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 Debugger.start and Debugger.stop.
        """

        import trepan.lib.core as Mcore

        self.mainpyfile  = None
        self.thread      = None
        self.eval_string = None
        get_option = lambda key: option_set(opts, key,
                                            self.DEFAULT_INIT_OPTS)
        completer  = lambda text, state: self.complete(text, state)

        # set the instance variables that come directly from options.
        for opt in ('settings', 'orig_sys_argv', 'from_ipython'):
            setattr(self, opt, get_option(opt))
            pass

        core_opts = {}
        for opt in ('ignore_filter', 'proc_opts', 'processor', 'step_ignore',
                    'processor',):
            core_opts[opt] = get_option(opt)
            pass

        # How is I/O for this debugger handled? This should
        # be set before calling DebuggerCore.
        interface_opts={'complete': completer}
        # FIXME when I pass in opts=opts things break
        interface = (get_option('interface') or
                     Muser.UserInterface(opts=interface_opts))
        self.intf = [interface]

        inp = get_option('input')
        if inp:
            self.intf[-1].input = inp
            pass

        out = get_option('output')
        if out:
            self.intf[-1].output = out
            pass

        self.core = Mcore.DebuggerCore(self, core_opts)
        self.core.add_ignore(self.core.stop)

        # When set True, we'll also suspend our debug-hook tracing.
        # This gives us a way to prevent or allow self debugging.
        self.core.trace_hook_suspend = False

        if get_option('save_sys_argv'):
            # Save the debugged program's sys.argv? We do this so that
            # when the debugged script munges these, we have a good
            # copy to use for an exec restart
            self.program_sys_argv = list(sys.argv)
        else:
            self.program_sys_argv = None
            pass

        self.sigmgr = Msig.SignalManager(self)

        # Were we requested to activate immediately?
        if get_option('activate'):
            self.core.start(get_option('start_opts'))
            pass
        return

    def complete(self, last_token, state):
        if hasattr(self.core.processor, 'completer'):
            str = get_line_buffer() or last_token
            results = self.core.processor.completer(str, state)
            return results[state]
        else:
            return [None]
    pass
Esempio n. 4
0
 def setUp(self):
     global ignore_filter
     trace_lines = []
     ignore_tracefilter = tracefilter.TraceFilter()
     return
Esempio n. 5
0
#!/usr/bin/env python
# -*- Python -*-
"Unit test for Tracer's add-hook"
import operator, os, sys, unittest
import tracer, tracefilter

trace_lines = []
ignore_filter = tracefilter.TraceFilter([tracer.stop])

def trace_dispatch1(frame, event, arg):
    return trace_dispatch1

def trace_dispatch2(frame, event, arg):
    return trace_dispatch2

def trace_dispatch3(frame, event, arg):
    return trace_dispatch3

class TestTraceAddHook(unittest.TestCase):

    def setUp(self):
        global ignore_filter
        trace_lines = []
        ignore_tracefilter = tracefilter.TraceFilter()
        return

    def test_add_hook(self):
        """Basic sanity and status testing."""
        self.assertEqual(0, tracer.size())
        self.assertEqual(1, tracer.add_hook(trace_dispatch1))
        self.assertEqual(2, tracer.add_hook(trace_dispatch2))
Esempio n. 6
0
        STARTED_STATE = False
        return len(HOOKS)
    raise NotImplementedError("sys.settrace() doesn't seem to be implemented")


# Demo it
if __name__ == '__main__':

    t = list(EVENT2SHORT.keys())
    t.sort()
    print("EVENT2SHORT.keys() == ALL_EVENT_NAMES: %s" %
          (tuple(t) == ALL_EVENT_NAMES))
    trace_count = 10

    import tracefilter
    ignore_filter = tracefilter.TraceFilter([find_hook, stop, remove_hook])

    def my_trace_dispatch(frame, event, arg):
        global trace_count, ignore_filter
        'A sample trace function'
        if ignore_filter.is_included(frame): return None
        lineno = frame.f_lineno
        filename = frame.f_code.co_filename
        s = "%s - %s:%d" % (event, filename, lineno)
        if 'call' == event:
            s += (', %s()' % frame.f_code.co_name)
        if arg:
            print("%s arg %s" % (s, arg))
        else:
            print(s)
            pass