'Full gdb Pretty-Printer class syntax for simple C++ class example
After reading all Pretty-Printer posts on this forum I can find and the GDB wiki, I still can not get my head around the correct syntax for my use cases. I got the basics about how to start them and how they work. I saw some very easy to understand examples, but beyond that only the very complex std::container style examples which were well beyond my rather python know-how. I found a lot of fractional pieces, but I could not get them together. So in this question I am looking for a still simple but complete Pretty-printer for debugging C++ code. There are a bit above trivial by using class members of own classes, pointers to own classes, and a vector with a pointers to own classes. All that is stuff I could not get to work in a custom pretty printer.
So please consider this example C++ class that should be pretty-printed:
namespace test {
class MyData {
MyData() { nNumber1=1; nNumber2=4; nNUmber3=6; name="foo"; }
int nNumber1;
int nNumber2;
int nNumber3;
std::string name;
};
class MyObject {
MyData Datablock1;
MyData* pDatablock2;
std::vector<MyData*> vDataBlocks;
};
}
This is the code section that should be debugged:
test::MyObject Test1;
test::MyObject* pTest2 = new test::MyObject();
//...
std::cout << Test1 << "\n";
std::cout << pTest2 << "\n";
std::cout << *pTest2 << "\n"; // break after this line
This is the desired gdb output from the pretty printers
(gdb) output Test1.Datablock1
[1,4,6,"foo"]
(gdb) output pTest1.pDatablock2
(test::MyData*) 0x122dfecab223, [1,4,6,"foo"]
(gdb) output pTest2
(MyObject*) 0x122dfecaa044, vectorLenght=7
(gdb) output *pTest2
DataBlock1=[1,4,6,"foo"]; Datablock2=(test::MyData*)0x122dfec0032, [1,4,6,"foo"]; vDataBlocks=lenght 3, {[1,4,6,"foo"],[1,4,6,"foo"],[1,4,6,"foo"]}
From what I understand this is how the "printer.py" file looks like. The ??? sections is where I got stuck. Maybe I am also missing bits.
import gdb
class MyDataPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return '[{},{},{},{}]'.format( self.val['nNumber1'], self.val['nNumber1'], self.val['nNumber1'], self.val['name'] )
class MyDataPtrPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return ????
class MyObjectPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return ?????????
class MyObjectPtrPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return ???????
def my_pp_func(val):
if str(val.type) == 'MyData': return MyDataPrinter(val)
if str(val.type) == 'MyData*': return MyDataPtrPrinter(val)
elif str(val.type) == 'MyObject': return MyObjectPrinter(val)
elif str(val.type) == 'MyObject*': return MyObjectPtrPrinter(val)
return None
gdb.pretty_printers.append(my_pp_func)
Its not clear to me how to dereference pointers correctly (i.e. probably involving dereference() ) and how get the output of the vector referenced and put into a single return string.
Most examples I found used the gdb print command and not the "toString" python function. So I figured basically what to to but I miserably failed to get it all together. Most errors I got was "Invalid Syntax" caused by trying to use pieces like some_struct_ptr.dereference()['some_var'] or *(myVector._M_impl._M_start)@myVector.size() with replacing myVector by self.val.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
