Reputation: 123
when I write code in Java, I use the debugger embedded in Eclipse. When visualizing an object in this context, the debugger automatically calls the toString() function, feature that I find very convenient for quick visualization while exploring program state.
Now, when I work in C, I use emacs+gdb for debugging, but I didn't manage to find/recreate an equivalent feature for visualizing complicated C structures (i.e. call a specific printing function). Of course there is no general toString() method, but anyway I very often have implemented somewhere a printing function for my structures.
But when I want to visualize something in gdb, I have to call these printing functions manually from gdb doing p my_print_function(my_struct_pointer)
, which is quite inefficient (have to remember its name, type it correctly, moreover the standard output may be in another windows...).
The thing I'd like is to configure gdb to say "when calling gdb print function on the struct pointer type T, call automatically that user-defined printing function f...". Is there a way to do this ? Thanks in advance.
Upvotes: 11
Views: 2191
Reputation: 123
Although I had no time to learn all the gdb/python pretty-printing theory, I found a simple way to reuse my C printers in gdb.
Example to link the structs "struct_name_1" and "struct_name_2" to the C function "struct_printer_1_c_func" and "struct_printer_2_c_func" :
1) Create a file struct_printers.py
class Pstruct (gdb.Function):
"""Returns a string describing a struct...
"""
def __init__ (self):
super (Pstruct, self).__init__ ("pstruct")
def invoke (self, name):
expr_type = name.dereference().type.tag
expr_string = name.__str__()
expr_address = expr_string.split(" ")[0]
if (cmp(expr_type, "struct_name_1") == 0):
return gdb.parse_and_eval("struct_printer_1_c_func("+ expr_address +")")
elif (cmp(expr_type, "struct_name_2") == 0):
return gdb.parse_and_eval("struct_printer_2_c_func("+ expr_address +")")
else:
print "[No struct printer for this type]"
return gdb.parse_and_eval(expr_address)
Pstruct ()
2) Add this to your .gdbinit :
source struct_printers.py
define pstruct
p $pstruct($arg0)
end
Then when your are in gdb in front of a pointer to a struct you want to examine, call pstruct instead of print.
Probably ugly and poorly extensible, but works well enough for what I needed (however I would be pleased I someone knows the correct way to do this with the python pretty-printing stuff).
Upvotes: 1
Reputation: 1151
use print struct_var
to print members of a given struct
use print *struct_ptr
to print members of a given struct pointer
use set print pretty on
if you want gdb to print structures in an indented format with one member per line, like this:
$1 = {
next = 0x0,
flags = {
sweet = 1,
sour = 1
},
meat = 0x54 "Pork"
}
and also you can use ptype struct_var
to print out the definition of a given struct
more info here
Upvotes: 7
Reputation: 399813
Good question.
Yes, kind of I guess. It seems GDB 7 has support for "pretty-printers" written in Python. Not as convenient (in my opinion) as using the already-written code in the actual target language, but perhaps good enough.
These are the commands for working with pretty-printers.
Upvotes: 5