22.214.171.124 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.
gdb.Progspace contains a
gdb.Objfile also contains a
A function on one of these lists is passed a single
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
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
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
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
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 ())