Reputation: 241
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
Upvotes: 5
Views: 622
Reputation: 27214
I don’t see a reason why adding this wouldn’t be sufficient.
class TestStructPrinter(InnerStructPrinter):
def __init__(self, val):
super().__init__(val['array'])
pp.add_printer('TestStruct', '^TestStruct$', TestStructPrinter)
In other words, the sub-fields are accessed simply as val['field']['subfield']
. The subclassing is something of a hack, but you get the idea.
Sample session:
(gdb) show version
GNU gdb (Debian 9.2-1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
[…]
(gdb) python print(sys.version)
3.8.6 (default, Sep 25 2020, 09:36:53)
[GCC 10.2.0]
(gdb) print s
$1 = InnerStruct of length 2 = {5, 8}
(gdb) print s.array
$2 = InnerStruct of length 2 = {5, 8}
This seems a rather silly thing to do, though: a debugger is supposed to help you tell types apart. By making TestStruct
and InnerStruct
print out the same, it will instead mislead the user into thinking one type is being used instead of the other, and have them attempt to access, say, s.buffer
instead of s.array.buffer
.
Upvotes: 2