23.2.2.6 Selecting Pretty-Printers

The Python list gdb.pretty_printers contains an array of functions or callable objects that have been registered via addition as a pretty-printer. Each gdb.Progspace contains a pretty_printers attribute. Each gdb.Objfile also contains a pretty_printers attribute.

A function on one of these lists is passed a single gdb.Value argument and should return a pretty-printer object conforming to the interface definition above (see Pretty Printing API). If a function cannot create a pretty-printer for the value, it should return None.

gdb first checks the pretty_printers attribute of each gdb.Objfile in the current program space and iteratively calls each enabled function (see Disabling Pretty-Printers) in the list for that gdb.Objfile until it receives a pretty-printer object. If no pretty-printer is found in the objfile lists, gdb then searches the pretty-printer list of the current program space, calling each enabled function until an object is returned. After these lists have been exhausted, it tries the global gdb.pretty_printers list, again calling each enabled function until an object is returned.

The order in which the objfiles are searched is not specified. For a given list, functions are always invoked from the head of the list, and iterated over sequentially until the end of the list, or a printer object is returned.

Here is an example showing how a std::string printer might be written:

     class StdStringPrinter:
         "Print a std::string"
     
         def __init__ (self, val):
             self.val = val
     
         def to_string (self):
             return self.val['_M_dataplus']['_M_p']
     
         def display_hint (self):
             return 'string'

And here is an example showing how a lookup function for the printer example above might be written.

     def str_lookup_function (val):
     
         lookup_tag = val.type.tag
         regex = re.compile ("^std::basic_string<char,.*>$")
         if lookup_tag == None:
             return None
         if regex.match (lookup_tag):
             return StdStringPrinter (val)
     
         return None

The example lookup function extracts the value's type, and attempts to match it to a type that it can pretty-print. If it is a type the printer can pretty-print, it will return a printer object. If not, it returns None.

We recommend that you put your core pretty-printers into a Python package. If your pretty-printers are for use with a library, we further recommend embedding a version number into the package name. This practice will enable gdb to load multiple versions of your pretty-printers at the same time, because they will have different names.

You should write auto-loaded code (see Auto-loading) such that it can be evaluated multiple times without changing its meaning. An ideal auto-load file will consist solely of imports of your printer modules, followed by a call to a register pretty-printers with the current objfile.

Taken as a whole, this approach will scale nicely to multiple inferiors, each potentially using a different library version. Embedding a version number in the Python package name will ensure that gdb is able to load both sets of printers simultaneously. Then, because the search for pretty-printers is done by objfile, and because your auto-loaded code took care to register your library's printers with a specific objfile, gdb will find the correct printers for the specific version of the library used by each inferior.

To continue the std::string example (see Pretty Printing API), this code might appear in gdb.libstdcxx.v6:

     def register_printers (objfile):
         objfile.pretty_printers.add (str_lookup_function)

And then the corresponding contents of the auto-load file would be:

     import gdb.libstdcxx.v6
     gdb.libstdcxx.v6.register_printers (gdb.current_objfile ())