Hobbes
Hobbes

Reputation: 123

Defining gdb print function for C structures

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

Answers (3)

Hobbes
Hobbes

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

swpd
swpd

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

unwind
unwind

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

Related Questions