This is the mail archive of the gdb@sourceware.org mailing list for the GDB 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]

Pretty-printers for members can't be influenced by pretty-printers for their containing structure


Here's a difficulty I've run into using GDB's pretty-printer API.

Mozilla's JavaScript engine uses a number of struct types that contain
unions. I'd like to define a pretty-printer such that the dead union
branches simply don't show up. Here's an example, from our string
representation.

struct JSString {
    struct Data
    {
        size_t                     lengthAndFlags;      /* JSString */
        union {
            const jschar           *chars;              /* JSLinearString */
            JSString               *left;               /* JSRope */
        } u1;
        union {
            jschar                 inlineStorage[NUM_INLINE_CHARS]; /*
JS(Inline|Short)String */
            struct {
                union {
                    JSLinearString *base;               /*
JS(Dependent|Undepended)String */
                    JSString       *right;              /* JSRope */
                    size_t         capacity;            /*
JSFlatString (extensible) */
                    const JSStringFinalizer *externalFinalizer;/*
JSExternalString */
                } u2;
                union {
                    JSString       *parent;             /* JSRope (temporary) */
                    size_t         reserved;            /* may use for
bug 615290 */
                } u3;
            } s;
        };
    } d;
...

Assume I'm looking at the struct itself, not trying to find the text
it represents. (I handle that angle elsewhere just fine.)

Some bits of the lengthAndFlags member serve as a tag indicating which
fields of the unions are live. If what I've actually got is a JSRope,
say, representing the concatenation of two strings, then d.u1.left and
d.s.u2.right are live, and the overlapping union members like
d.u1.chars should be omitted, as they're just garbage.

Certainly, I can write a pretty-printer that just generates a string like this:

   { lengthAndFlags = blah, u1 = { left = blah }, s = { right = blah } ... }

But then I have to re-implement all the relevant 'set print'
parameters myself, like 'set print pretty' or 'set print address'. It
would be much nicer if I could simply have the pretty-printer provide
a 'children' method that skips dead union branches, and leave GDB's
own code responsible for respecting those parameters. That is, if the
pretty-printer could describe the structure at an appropriate level of
abstraction, I wouldn't need to re-implement bits of GDB.

Unfortunately, I can't do that. The pretty-printer for JSString::Data
can report 'u1' as one of its children, but then when I'm asked to
create a pretty-printer for that 'u1' value, I have no way of finding
the JSString::Data instance from which it was extracted. I've lost the
context I need to make a pretty-printer that lists only 'left' (say)
as a child, omitting 'chars'.

One possible fix would be to allow the second element of the 2-tuple
items produced by the iterator returned by the pretty-printer's
'children' method to be a new pretty-printer. The set of Python values
that GDB will convert to gdb.Values doesn't include any object types,
so this is unambiguous.

If GDB worked this way, then the pretty-printer for JSString::Data
could consult 'lengthAndFlags', and then list ('u1', P) as one of its
children, where P is a pretty-printer that knows which of its branches
is live.

How does this sound? Am I looking for a solution in the wrong place?
Is there a better way to get what I want?


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