Exemplo n.º 1
0
    def get_source_desc(self, frame):
        filename = lineno = lexer = None
        if self.is_cython_function(frame):
            filename = self.get_cython_function(frame).module.filename
            lineno = self.get_cython_lineno(frame)
            if pygments:
                lexer = pygments.lexers.CythonLexer(stripall=False)
        elif self.is_python_function(frame):
            pyframeobject = libpython.Frame(frame).get_pyop()

            if not pyframeobject:
                raise gdb.GdbError(
                    'Unable to read information on python frame')

            filename = pyframeobject.filename()
            lineno = pyframeobject.current_line_num()

            if pygments:
                lexer = pygments.lexers.PythonLexer(stripall=False)
        else:
            symbol_and_line_obj = frame.find_sal()
            if not symbol_and_line_obj or not symbol_and_line_obj.symtab:
                filename = None
                lineno = 0
            else:
                filename = symbol_and_line_obj.symtab.fullname()
                lineno = symbol_and_line_obj.line
                if pygments:
                    lexer = pygments.lexers.CLexer(stripall=False)

        return SourceFileDescriptor(filename, lexer), lineno
Exemplo n.º 2
0
    def print_stackframe(self, frame, index, is_c=False):
        """
        Print a C, Cython or Python stack frame and the line of source code
        if available.
        """
        # do this to prevent the require_cython_frame decorator from
        # raising GdbError when calling self.cy.cy_cvalue.invoke()
        selected_frame = gdb.selected_frame()
        frame.select()

        try:
            source_desc, lineno = self.get_source_desc(frame)
        except NoFunctionNameInFrameError:
            print '#%-2d Unknown Frame (compile with -g)' % index
            return

        if not is_c and self.is_python_function(frame):
            pyframe = libpython.Frame(frame).get_pyop()
            if pyframe is None or pyframe.is_optimized_out():
                # print this python function as a C function
                return self.print_stackframe(frame, index, is_c=True)

            func_name = pyframe.co_name
            func_cname = 'PyEval_EvalFrameEx'
            func_args = []
        elif self.is_cython_function(frame):
            cyfunc = self.get_cython_function(frame)
            f = lambda arg: self.cy.cy_cvalue.invoke(arg, frame=frame)

            func_name = cyfunc.name
            func_cname = cyfunc.cname
            func_args = []  # [(arg, f(arg)) for arg in cyfunc.arguments]
        else:
            source_desc, lineno = self.get_source_desc(frame)
            func_name = frame.name()
            func_cname = func_name
            func_args = []

        try:
            gdb_value = gdb.parse_and_eval(func_cname)
        except RuntimeError:
            func_address = 0
        else:
            # Seriously? Why is the address not an int?
            func_address = int(str(gdb_value.address).split()[0], 0)

        a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
        print '#%-2d 0x%016x in %s(%s)' % (index, func_address, func_name, a),

        if source_desc.filename is not None:
            print 'at %s:%s' % (source_desc.filename, lineno),

        print

        try:
            print '    ' + source_desc.get_source(lineno)
        except gdb.GdbError:
            pass

        selected_frame.select()
Exemplo n.º 3
0
 def is_python_function(self, frame):
     """
     Tells if a frame is associated with a Python function.
     If we can't read the Python frame information, don't regard it as such.
     """
     if frame.name() == 'PyEval_EvalFrameEx':
         pyframe = libpython.Frame(frame).get_pyop()
         return pyframe and not pyframe.is_optimized_out()
     return False
Exemplo n.º 4
0
    def test_python_step(self):
        self.break_and_run('os.path.join("foo", "bar")')

        result = gdb.execute('cy step', to_string=True)

        curframe = gdb.selected_frame()
        self.assertEqual(curframe.name(), 'PyEval_EvalFrameEx')

        pyframe = libpython.Frame(curframe).get_pyop()
        # With Python 3 inferiors, pyframe.co_name will return a PyUnicodePtr,
        # be compatible
        frame_name = pyframe.co_name.proxyval(set())
        self.assertEqual(frame_name, 'join')
        assert re.match(r'\d+    def join\(', result), result
Exemplo n.º 5
0
        def print_stackframe(self, frame, index, is_c=False):
            if not is_c and self.is_python_function(frame):
                pyframe = libpython.Frame(frame).get_pyop()
                if pyframe is None or pyframe.is_optimized_out():
                    # print this python function as a C function
                    return self.print_stackframe(frame, index, is_c=True)
                func_name = pyframe.co_name
                func_cname = 'PyEval_EvalFrameEx'
                func_args = []
            elif self.is_cython_function(frame):
                cyfunc = self.get_cython_function(frame)
                # f = lambda arg: self.cy.cy_cvalue.invoke(arg, frame=frame)

                func_name = cyfunc.name
                func_cname = cyfunc.cname
                func_args = []  # [(arg, f(arg)) for arg in cyfunc.arguments]
            else:
                func_name = frame.name()
                func_cname = func_name
                func_args = []

            try:
                gdb_value = gdb.parse_and_eval(func_cname)
            except (RuntimeError, TypeError):
                func_address = 0
            else:
                func_address = int(str(gdb_value.address).split()[0], 0)

            out = '#%-2d 0x%016x' % (index, func_address)
            try:
                a = ', '.join('%s=%s' % (name, val) for name, val in func_args)
                out += ' in %s (%s)' % (func_name or "??", a)
                source_desc, lineno = self.get_source_desc(frame)
                if source_desc.filename is not None:
                    out += ' at %s:%s' % (source_desc.filename, lineno)
            except Exception:
                return
            finally:
                print(out)

            try:
                source = source_desc.get_source(lineno - 5,
                                                lineno + 5,
                                                mark_line=lineno,
                                                lex_entire=True)
                print(source)
            except gdb.GdbError:
                pass