This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Fix glitches with libstdc++ pretty printers


On Mon, Dec 22, 2008 at 2:26 PM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes:
>
> Paul> Hmm, an easy way to solve this would be to say that if Foo inherits
> Paul> from Bar, and if Bar has a pretty-printer but Foo doesn't, then
> Paul> the Bar pretty-printer is used.
>
> Paul> With that, I only need to define one pretty-printer :)
>
> This same problem came up in the GObject context.
>
> I do wonder whether regexp on the type name is the best way to
> associate types with printer constructors.
>
>
> One idea I had was that the -gdb.py code could iterate over the types
> defined in the current objfile and set up the dictionary using the
> results.  We'd have to write some more Python glue to make this
> possible, but we'll need that anyway.
>
> This would let you implement printing-via-inheritance.  We could even
> supply a utility function to make it simple.
>
> The down side of this approach is that (I think) it requires loading
> the symbols, which interacts poorly with the lazy-reading branch,
> which we also want.
>
>
> Another idea is to run a hook when a type is created, and do the
> association directly, not by name.  My worry here is that we'd see a
> noticeable performance hit.

In a given GDB session, a great majority of types will not be
examined by the end-user, so it seems wasteful to examine type
hierarchies and create pretty-printers for the types which will
never be accesses.

It appears to me that the current "on demand" solution is better.

> Finally, you can do it already, with a bit of difficulty.  You can
> install a printer constructor for any struct type, and then have it
> examine the type hierarchy.

Except (AFAICT) gdb.Type doesn't (yet) give access to ancestors.
So I believe I can't do it this way just yet.

The other difficulty is that (in C++) the type is (somewhat
unintuitively) called '^Foo$' (unlike C, where it is called
'^struct Foo$'), so I'd have to examine every possible type, not
just structs.

> If the desired ancestor is not found, it
> can return None, and the C code will look for the next printer.  You
> can even register the newly discovered type in the map for faster
> access the next time.
>
> I imagine this is pretty slow, but I have not tried it.  I think it
> would be preferable to come up with something nicer if we can.
>
> Right now I'm not sure what exactly I want to do.  Gathering
> requirements is always a good first step...
>
> Tom
>

I've implemented the "automatically recursively search ancestors"
solution (patch attached), and will "unleash" it on my users.

We'll know in about a month how well (or how poorly) this works here.

Thanks,
-- 
Paul Pluzhnikov
From b3072c1e2734e83ce2d45ec755de0089d2125845 Mon Sep 17 00:00:00 2001
From: Paul Pluzhnikov <ppluzhnikov@google.com>
Date: Mon, 22 Dec 2008 14:09:16 -0800
Subject: [PATCH] Recursive search for pretty-printers.

---
 gdb/ChangeLog       |    5 +++++
 gdb/python/python.c |   34 +++++++++++++++++++++++++++++++++-
 2 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 05cfb87..d08ea03 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-22  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+	* python/python.c (find_pretty_printer): Recursive search
+	for base class pretty-printer.
+	
 2008-12-17  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
 	* python/lib/gdb/libstdcxx/v6/printers.py: Iterator pretty-printers.
diff --git a/gdb/python/python.c b/gdb/python/python.c
index c2943cc..b662f7f 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -863,7 +863,7 @@ search_pp_dictionary (PyObject *dict, char *type_name)
    pretty-printer exists, return NULL.  If one exists, return a new
    reference.  */
 static PyObject *
-find_pretty_printer (struct type *type)
+find_pretty_printer_1 (struct type *type)
 {
   PyObject *dict, *found = NULL;
   char *type_name = NULL;
@@ -920,6 +920,38 @@ find_pretty_printer (struct type *type)
   return found;
 }
 
+static PyObject *
+find_pretty_printer (struct type *type)
+{
+  extern int opaque_type_resolution;
+  int i;
+  PyObject *printer;
+
+  if (TYPE_CODE (type) == TYPE_CODE_REF)
+    type = TYPE_TARGET_TYPE (type);
+
+  printer = find_pretty_printer_1 (type);
+  if (printer
+      || (TYPE_CODE (type) != TYPE_CODE_STRUCT
+	  && TYPE_CODE (type) != TYPE_CODE_UNION))
+    return printer;
+
+  if (TYPE_IS_OPAQUE (type) && opaque_type_resolution)
+    {
+      char *name = type_name_no_tag (type);
+      if (name != NULL)
+	type = lookup_transparent_type (name);
+    }
+  for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+    {
+      struct type *t = TYPE_BASECLASS (type, i);
+      printer = find_pretty_printer (t);
+      if (printer)
+	return printer;
+    }
+  return NULL;
+}
+
 /* Pretty-print a single value, via the printer object PRINTER.  If
    the function returns a string, an xmalloc()d copy is returned.
    Otherwise, if the function returns a value, a *OUT_VALUE is set to
-- 
1.5.4.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]