Next: Commands In Python, Previous: Pretty Printing, Up: Python API
The Python list gdb.pretty_printers contains an array of
functions that have been registered via addition as a pretty-printer.
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). 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 and iteratively calls each function in the list for
that gdb.Objfile until it receives a pretty-printer object.
After these lists have been exhausted, it tries the global
gdb.pretty-printers list, again calling each 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),
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 ())