public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [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.
@ 2012-06-25 17:41 pmuldoon
  0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-06-25 17:41 UTC (permalink / raw)
  To: archer-commits

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 <pmuldoon@redhat.com>
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 "<unknown function>"
@@ -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 "<unknown filename>"
 
     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 "<unknown line>"
 
     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 "<unknown function>"
         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.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2012-06-25 17:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-25 17:41 [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 pmuldoon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).