Sunday, 15 November 2020

How do I get the inner value to use as an array for gdb pretty print?

I wrote a pretty printer for InnerStruct which shows the array as 2 elements and the values correctly. I also made a joke one for TestStruct2, However I have no idea how to make TestStruct contain the same contents as InnerStruct. I have no idea how to access array.nestedVariables from gdb/python. How do I write this so TestStruct gives the same results as InnerStruct?

Source

struct InnerStruct
{
    int buffer[100];
    int len;
};
struct TestStruct
{
    InnerStruct array;
};
struct TestStruct2
{
    InnerStruct array;
};

int main() {
    TestStruct s;
    s.array.buffer[0] = 5;
    s.array.buffer[1] = 8;
    s.array.len=2;
    TestStruct2 s2;
    s2.array.buffer[0] = 5;
    s2.array.buffer[1] = 8;
    s2.array.len=2;
    return 0;
}

.gdbinit

python

pp = gdb.printing.RegexpCollectionPrettyPrinter("pp")

class InnerStructPrinter:
    "Print a InnerStruct"

    class _iterator:
        def __init__ (self, start, finish):
            self.item = start
            self.finish = finish
            self.count = 0

        def __iter__ (self):
            return self

        def __next__ (self):
            count = self.count
            self.count = self.count + 1
            if self.item == self.finish:
                raise StopIteration
            elt = self.item.dereference()
            self.item = self.item + 1
            return ('[%d]' % count, elt)

        def next (self):
            return self.__next__()

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

    def children (self):
        start = self.val['buffer'][0].address
        return self._iterator(start, start + self.val['len'])

    def to_string (self):
        len = self.val['len']
        return '%s of length %d' % (self.val.type, len)

    def display_hint (self):
        return 'array'

pp.add_printer('InnerStruct', '^InnerStruct$', InnerStructPrinter)

class TestStruct2Printer:
    "Print a TestStruct2"

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

    def to_string (self):
        return "Array of"

    def children(self):
        yield ('0', 'fake')
        yield ('1', 'val')

    def display_hint (self):
        return 'array'

pp.add_printer('TestStruct2', '^TestStruct2$', TestStruct2Printer)

gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
end


from How do I get the inner value to use as an array for gdb pretty print?

No comments:

Post a Comment