This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
kudos and suggestions
- From: Graydon Hoare <graydon at pobox dot com>
- To: archer at sourceware dot org
- Date: Thu, 27 Nov 2008 11:14:58 -0800
- Subject: kudos and suggestions
Hi,
I'm very happy to be using the new python scripting facility in archer;
particularly the pretty-printer, though no doubt I'll find the functions
extremely useful once I start digging into them as well.
I was wondering if I might make a suggestion about pretty-printing, or
in general about the boundary between what a pretty-printer does and
what the rest of the debugger does. I make this suggestion in complete
ignorance of the machinery inside gdb and therefore am quite
understanding if the response is "that's way too much work".
In the data structures I'm most likely to want to take apart, it is not
simply a matter of presenting the object in an appealing form: it's more
fully a matter of "demangling memory", where the components of the
objects are somewhat obscure, say, accessed through tagged pointers or
variable-sized objects or small offsets in implicit tables or such. So
"pretty printing" is only a summary of what I want; what I *really* want
is the ability to have "a hook of my choice" perform the task of "child
enumeration" to multiple parts of gdb.
For example, if I register a hook on a type T, I want a value v of type
T to pretty-print of course, but I also want it to be true that the
keyboard sequence "v.<tab>" calls my hook to analyze v, and returns the
child-value list from the analysis for my tab-completion prompt, and if
child "foo" was in that list, then the keyboard sequence "v.foo" asks my
hook for the foo'th child of v, and so forth.
In other words, I would like to be able to "fully virtualize" (or
"mostly virtualize", with whatever exceptions are essential to gdb's
sanity) the exploration of a data structure via a python hook. In a
sense this is more work than what you're already doing, but in a sense I
think it might be less too, since it's not specifically related to the
pretty-printer. At least in a perfect world.
I say this because I'm comparing to the experience of working with the
system in visual studio, which exists less as a full printer and more as
a "single step" in the incremental exploration of pointer graphs. So I'm
noticing, despite the significantly nicer language in use here, a
usability gap: with the current gdb arrangement my printer-hook has to
decide how deep to go, and then "give up" and just print raw addresses.
I can then copy, paste, and cast those addresses to resume exploration
of sub-structures via my mouse. But v.foo.bar.baz is much nicer than 3
copy-paste-cast cycles.
If that is infeasible, however, it would at least be nice to have two
modifications made to the pretty-printing interface:
- Separate hooks for pretty-printing a node in "summary" and "full"
modes. When I return a child list (or when a value appears in a
"small" context such as in a context line in a backtrace) it is
convenient to do what gdb currently does with strings: "dereference
the pointer and show a short summary of what's on the other end".
If you have only one mode for pretty printing, as now, the hook
can't know whether to dereference pointers or not; if you do, you
possibly recur endlessly. If you don't, you possibly fail to
dereference pointers to "obviously little" values like strings and
numbers, where the referent is far more useful to display inline
than the address.
- The ability, as suggested earlier, to ask gdb to take over and
"do what it would normally do, to this value" at any point.
Requiring the root hook to "return None" is not quite enough,
for two reasons:
- First, it may only occur to a hook that it wants to give up
quite deep in the analysis of a structure. So it might want to
raise a StdPrint sort of exception back to gdb. This *could* be
done by a root hook that tries, catches, and returns None,
except...
- In printing a recursive value structure, it's possibly the case
that I want to give up and transfer control to the default
printer applied *to a value other than the one I was invoked
on*. So ideally I want to be able to raise StdPrint(v) for
some sub-value v that my hook discovered.
One other nit I've discovered so far (and please, consider it high
praise that there's only been really one, the interface is very good!)
is that converting from a gdb Value of an enumerated C type to its
pythonic integer value is not-entirely trivial. I have to guess the
compiler's representation type and perform a cast, such as:
int(v.cast(gdb.Type('uint8_t')))
assuming that the enum wound up being 8 bits or fewer. It'd be nice to
be able to do int(v), or long(v), or whatever the python ideal is.
Thanks though, and please keep it up! This is all a big step forward for
gdb usability.
-Graydon