'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