From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25659 invoked by alias); 25 Jun 2012 17:41:28 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 25437 invoked by uid 9514); 25 Jun 2012 17:41:25 -0000 Date: Mon, 25 Jun 2012 17:41:00 -0000 Message-ID: <20120625174124.25394.qmail@sourceware.org> From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-backtrace: Use a Primordial filter if a gdb.Frame is left unwrapped. Pass through values of wrapped filters that are also wrapped by another filter. X-Git-Refname: refs/heads/archer-pmuldoon-python-backtrace X-Git-Reftype: branch X-Git-Oldrev: 01ab5c800ea2fc5ae1720880879c33a5ee2aef97 X-Git-Newrev: 95041c461af676b94e1230bc319b4fe937740b07 X-SW-Source: 2012-q2/txt/msg00064.txt.bz2 List-Id: The branch, archer-pmuldoon-python-backtrace has been updated via 95041c461af676b94e1230bc319b4fe937740b07 (commit) from 01ab5c800ea2fc5ae1720880879c33a5ee2aef97 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 95041c461af676b94e1230bc319b4fe937740b07 Author: Phil Muldoon Date: Mon Jun 25 18:40:36 2012 +0100 Use a Primordial filter if a gdb.Frame is left unwrapped. Pass through values of wrapped filters that are also wrapped by another filter. ----------------------------------------------------------------------- Summary of changes: gdb/python/lib/gdb/FrameWrapper.py | 36 ++++++++- gdb/python/lib/gdb/command/frame_filters.py | 19 +++++ gdb/python/py-framefilter.c | 110 ++++++++++++++++----------- gdb/testsuite/gdb.python/py-framefilter.exp | 14 +++- gdb/testsuite/gdb.python/py-framefilter.py | 30 +++----- 5 files changed, 138 insertions(+), 71 deletions(-) First 500 lines of diff: diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py index 0aa7870..91ae620 100644 --- a/gdb/python/lib/gdb/FrameWrapper.py +++ b/gdb/python/lib/gdb/FrameWrapper.py @@ -15,15 +15,17 @@ import gdb -class FrameWrapper: +class FrameWrapper (object): "Base Frame Wrapper" - def __init__ (self, frame): + # frame her can refer to a gdb.Frame or another frame like object + # conforming to the interface in this class. As we can have frame + # wrappers wrapping frame wrappers, we should defer to that + # object's method. + def __init__(self, frame): + super(FrameWrapper, self).__init__() self.frame = frame - def __new__ (self): - return self - def omit (self): return False @@ -31,6 +33,9 @@ class FrameWrapper: return False def function (self): + if hasattr(self.frame, "function"): + return str(self.frame.function()) + fname = str (self.frame.function()) if (fname == ""): return "" @@ -38,12 +43,21 @@ class FrameWrapper: return fname def level (self, level): + if hasattr(self.frame, "level"): + return self.frame.level() + return level def address (self): + if hasattr(self.frame, "address"): + return self.frame.address() + return self.frame.pc() def filename (self): + if hasattr(self.frame, "filename"): + return self.frame.filename() + sal = self.frame.find_sal() if (sal): return sal.symtab.filename @@ -51,6 +65,9 @@ class FrameWrapper: return "" def frame_args (self): + if hasattr(self.frame, "frame_args"): + return self.frame.frame_args() + args = self.frame.arguments() args_list = [] if args != None: @@ -61,6 +78,9 @@ class FrameWrapper: return args_list def frame_locals (self): + if hasattr(self.frame, "frame_locals"): + return self.frame.frame_locals() + frame_locals = self.frame.locals() frame_locals_list = [] if frame_locals != None: @@ -71,6 +91,9 @@ class FrameWrapper: return frame_locals_list def line (self): + if hasattr(self.frame, "line"): + return self.frame.line() + sal = self.frame.find_sal() if (sal): return sal.line @@ -78,6 +101,9 @@ class FrameWrapper: return "" def inferior_frame (self): + if hasattr(self.frame, "inferior_frame"): + return self.frame.inferior_frame() + return self.frame def older(self): diff --git a/gdb/python/lib/gdb/command/frame_filters.py b/gdb/python/lib/gdb/command/frame_filters.py index 3b76bf4..cec5d1c 100644 --- a/gdb/python/lib/gdb/command/frame_filters.py +++ b/gdb/python/lib/gdb/command/frame_filters.py @@ -20,6 +20,23 @@ import gdb import copy import gdb.FrameFilter from gdb.FrameIterator import FrameIterator +from gdb.FrameWrapper import FrameWrapper + +class PrimordialFilter: + + def filter_unwrapped (self, frame): + foo = gdb.Frame + if isinstance (frame, foo): + return True + else: + return False + + def filter (self, iterator): + for it in iterator: + if self.filter_unwrapped (it): + yield FrameWrapper(it) + else: + yield it def _parse_arg (cmd_name, arg): """ Internal Worker function to take an argument and return a @@ -164,6 +181,8 @@ def invoke (frame): for ff in sorted_list: frame_iterator = ff[1].filter (frame_iterator) + pri = PrimordialFilter () + frame_iterator = pri.filter (frame_iterator) return frame_iterator class InfoFrameFilter(gdb.Command): diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 5f729f8..42664f9 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -166,7 +166,7 @@ py_print_args (PyObject *filter, /* Frame arguments. */ annotate_frame_args (); ui_out_text (out, " ("); - + if (PyObject_HasAttrString (filter, "frame_args")) { PyObject *result = PyObject_CallMethod (filter, "frame_args", NULL); @@ -194,7 +194,7 @@ py_print_args (PyObject *filter, for (list_index = 0; list_index < size; list_index++) { - PyObject *sym_tuple, *sym, *value; + PyObject *sym_tuple, *sym, *value, *pvalue; const char *sym_name; struct value *val; struct symbol *symbol; @@ -248,8 +248,9 @@ py_print_args (PyObject *filter, annotate_arg_begin (); ui_out_field_string (out, "name", sym_name); ui_out_text (out, "="); - - val = value_object_to_value (value); + + val = convert_value_from_python (value); + // val = value_object_to_value (pvalue); if (! val) { PyErr_SetString (PyExc_RuntimeError, @@ -296,6 +297,34 @@ py_print_args (PyObject *filter, return 0; } +static CORE_ADDR +get_address (PyObject *filter, int *error) +{ + PyObject *result = NULL; + CORE_ADDR address = 0; + + *error = 0; + if (PyObject_HasAttrString (filter, "address")) + result = PyObject_CallMethod (filter, "address", NULL); + else + { + if (PyObject_HasAttrString (filter, "pc")) + result = PyObject_CallMethod (filter, "pc", NULL); + else + return 0; + } + + if (result) + { + address = PyLong_AsLong (result); + Py_DECREF (result); + } + else + *error = 1; + + return address; +} + static int py_print_frame (PyObject *filter, int print_level, @@ -313,7 +342,35 @@ py_print_frame (PyObject *filter, int line = 0; struct frame_info *frame = NULL; volatile struct gdb_exception except; + int error = 0; + + /* Get the frame. */ + if (PyObject_HasAttrString (filter, "inferior_frame")) + { + PyObject *result = PyObject_CallMethod (filter, "inferior_frame", NULL); + if (! result) + goto error; + if (result == Py_None) + gdbarch = target_gdbarch; + else + { + frame = frame_object_to_frame_info (result); + if (! frame) + { + Py_DECREF (result); + PyErr_SetString (PyExc_RuntimeError, + _("'inferior_frame' should return None, " \ + "or a gdb.Frame.")); + goto error; + } + gdbarch = get_frame_arch (frame); + } + Py_DECREF (result); + } + else + gdbarch = target_gdbarch; + /* First check to see if this frame is to be omitted. */ if (PyObject_HasAttrString (filter, "omit")) { @@ -344,30 +401,6 @@ py_print_frame (PyObject *filter, goto error; } - /* Get the frame. */ - if (PyObject_HasAttrString (filter, "inferior_frame")) - { - PyObject *result = PyObject_CallMethod (filter, "inferior_frame", NULL); - - if (! result) - goto error; - if (result == Py_None) - gdbarch = target_gdbarch; - else - { - frame = frame_object_to_frame_info (result); - if (! frame) - { - Py_DECREF (result); - goto error; - } - gdbarch = get_frame_arch (frame); - } - Py_DECREF (result); - } - else - gdbarch = target_gdbarch; - if (PyObject_HasAttrString (filter, "elide")) { PyObject *result = PyObject_CallMethod (filter, "elide", NULL); @@ -416,22 +449,11 @@ py_print_frame (PyObject *filter, else level = frame_relative_level (frame); } - - /* Print frame address. */ - if (PyObject_HasAttrString (filter, "address")) - { - PyObject *result = PyObject_CallMethod (filter, "address", NULL); - - if (result) - { - address = PyLong_AsLong (result); - Py_DECREF (result); - } - else - goto error; - } - else - address = 0; + + + address = get_address (filter, &error); + if (error) + goto error; annotate_frame_begin (print_level ? level : 0, gdbarch, address); diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp index 44b7de2..f6f5434 100644 --- a/gdb/testsuite/gdb.python/py-framefilter.exp +++ b/gdb/testsuite/gdb.python/py-framefilter.exp @@ -61,13 +61,23 @@ gdb_breakpoint [gdb_get_line_number "Backtrace end breakpoint"] gdb_continue_to_breakpoint "Backtrace end breakpoint" gdb_test "info frame-filter" \ - {.*100.*Yes.*Reverse.*10.*Yes.*Add.*1.*No.*Object.*1.*} + {.*100.*Yes.*Reverse.*10.*Yes.*Dummy.*1.*No.*Object.*1.*} # Test raw gdb_test "bt raw" \ {.*#0.*end_func.*#22.*in func1.*#27.*in main ().*} gdb_test "bt" \ {.*in Dummy function.*#22.*in 1cnuf.*#27.*in niam ().*} + +# Make the Dummy filter a higher priority than Reverse. This ensures +# we chain correctly. +gdb_test_no_output "set python frame-filter priority global Dummy 5000" gdb_test "bt" \ - {.*in Dummy function.*#22.*in 1cnuf.*#27.*in niam ().*} + {.*in noitcnuf ymmuD.*#22.*in 1cnuf.*#27.*in niam ().*} + +# Disable Reverse +gdb_test_no_output "set python frame-filter disable global Reverse" +gdb_test "bt" \ + {.*in Dummy function.*#22.*in func1.*#27.*in main ().*} remote_file host delete ${remote_python_file} + diff --git a/gdb/testsuite/gdb.python/py-framefilter.py b/gdb/testsuite/gdb.python/py-framefilter.py index 15f7a74..6ead587 100644 --- a/gdb/testsuite/gdb.python/py-framefilter.py +++ b/gdb/testsuite/gdb.python/py-framefilter.py @@ -22,8 +22,12 @@ from gdb.FrameWrapper import FrameWrapper class Reverse_Function (FrameWrapper): + def __init__(self, fobj): + super(Reverse_Function, self).__init__(fobj) + self.fobj = fobj + def function (self): - fname = str (self.frame.function()) + fname = str (self.fobj.function()) if (fname == ""): return "" else: @@ -31,21 +35,13 @@ class Reverse_Function (FrameWrapper): return fname def elide (self): - fname = str (self.frame.function()) + fname = str (self.fobj.function()) if (fname == "func2" or fname == "func3"): return True else: return False -class Dummy: - def __init__(self, nextframe): - self.nextframe = nextframe - - def omit (self): - return False - - def elide (self): - return False +class Dummy (): def function (self): return "Dummy function" @@ -57,7 +53,7 @@ class Dummy: return "Dummy filename" def frame_args (self): - return [] + return [("Foo",gdb.Value(12)),("Bar","Stuff"), ("FooBar",42)] def frame_locals (self): return [] @@ -65,25 +61,19 @@ class Dummy: def line (self): return 0 - def older (self): - return self.nextframe - def inferior_frame (self): return None class FrameAdd (): def __init__ (self): - self.name = "Add" + self.name = "Dummy" self.priority = 10 self.enabled = True gdb.frame_filters [self.name] = self def filter (self, frame_iter): - for f in frame_iter: - nextv = f - break - dummies = [Dummy(nextv)] + dummies = [Dummy()] frame_iter = itertools.chain (dummies, frame_iter) return frame_iter hooks/post-receive -- Repository for Project Archer.