GDB pretty-printing: returning string from a children()'s iterator, but displayed as a char[]
Asked Answered
H

1

6

I have a handy class that I use to allow me to easily add a set of "summariser" functions to a GDB pretty printer (for example, a Rect class could have an [Area] field, computed by Python). it then prints all the existing children as well, so you can see everything at once.

class SummaryAndFieldIterator:
    """
    Iterator to first go through a list of summariser functions,
    then display all the fields in the object in order
    """
    def __init__ (self, obj, summaries):
        self.count = 0
        self.obj = obj;
        self.summaries = summaries;
        self.keys = sorted(obj.type.iterkeys())

    def __iter__(self):
        return self

    def __next__(self):

        if (self.count >= len(self.keys) + len(self.summaries)):
            raise StopIteration
        elif self.count < len(self.summaries):

            name, retVal = self.summaries[self.count](self.obj)
            # FIXME: this doesn't seem to work when a string is returned
            # in retVal?
            result = "[%s]" % name, retVal

        else:
            field = self.count - len(self.summaries)
            result = self.keys[field], self.obj[self.keys[field]]

        self.count += 1
        return result

    next = __next__

class MyObjectPrinter:

    def __init__(self, val):
        self.val = val

    def get_int(self):
        return "meaning", 42

    def get_string(self):
        return "hoopiness", "Forty-two"

    def children(self):
        return SummaryAndFieldIterator(self.val, [self.get_string])

This works very well for the summarisers which return numeric values, but for strings, it ends up displaying as an array, so that I get

NAME                 VALUE
myobj                {..}
 |-->[meaning]      42
 |-->[hoopiness] 
      |-->[0]       'F'
      |-->[1]       'o'
       .....
 |-->real_field     34234

This is presumably becuase the string that comes from

name, retVal = self.summaries[self.count](self.obj)

does not generate a sufficiently "stringy" gdb.Value object when it is returned by SummaryAndFieldIterator's __next__ method. Adjusting the display_hint() method of MyObjectPrinter doesn't seem to have any effect (but I doubt it would, as this is the child, not the object).

Anyone know how to return a string from the children() iterator and get it to display as a string?

Hilar answered 20/10, 2014 at 18:3 Comment(2)
There isn't really enough information here to know what the problem is. In particular, what types did you try returning? I would have thought that a Python string or a gdb.LazyString would work fine. It's also worth inspecting the MI traffic. It could be a bug in the GUI, or even possibly a bug in varobj.Marchak
Any workaround for this problem?Joly
R
2

Okay, apparently this may be a bug related to the way that GDB/MI communicates with pretty-printers, Bugzilla created here : https://sourceware.org/bugzilla/show_bug.cgi?id=18282

Rippy answered 20/4, 2015 at 16:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.