为C结构定义gdb打印功能

时间:2013-03-01 11:24:13

标签: c emacs gdb

当我用Java编写代码时,我使用Eclipse中嵌入的调试器。在这个上下文中可视化对象时,调试器会自动调用toString()函数,这个函数在我探索程序状态时非常方便快速可视化。

现在,当我在C中工作时,我使用emacs + gdb进行调试,但是我没有设法找到/重新创建用于可视化复杂C结构的等效功能(即调用特定的打印功能)。当然没有通用的toString()方法,但无论如何我经常在某处为我的结构实现打印功能。

但是当我想在gdb中可视化某些东西时,我必须从gdb手动调用这些打印函数p my_print_function(my_struct_pointer),效率非常低(必须记住它的名字,正确输入,而且标准输出可能在另一个窗口......)。

我想要的是配置gdb说“当在结构指针类型 T 上调用gdb打印函数时,自动调用用户定义的打印函数 f ...“。有没有办法做到这一点 ?提前谢谢。

3 个答案:

答案 0 :(得分:7)

使用print struct_var打印给定结构的成员

使用print *struct_ptr打印给定结构指针的成员

如果您希望gdb以缩进格式打印结构,每行一个成员,请使用set print pretty on,如下所示:

$1 = {
        next = 0x0,
        flags = {
          sweet = 1,
          sour = 1
        },
        meat = 0x54 "Pork"
      }

并且您也可以使用ptype struct_var打印出给定结构的定义

更多信息here

答案 1 :(得分:5)

好问题。

是的,我想。似乎GDB 7支持"pretty-printers" written in Python。不像我在实际目标语言中使用已编写的代码那样方便(在我看来),但也许还不错。

These are the commands与漂亮的打印机合作。

答案 2 :(得分:1)

虽然我没有时间学习所有gdb / python漂亮打印理论,但我找到了一种在gdb中重用C打印机的简单方法。

将结构“struct_name_1”和“struct_name_2”链接到C函数“struct_printer_1_c_func”和“struct_printer_2_c_func”的示例:

1)创建一个文件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)将其添加到.gdbinit:

source struct_printers.py

define pstruct  
p $pstruct($arg0) 
end

然后当你在指向要检查的结构的指针前面的gdb中时,调用pstruct而不是print。

可能是丑陋且可扩展性差,但是对于我需要的东西来说效果很好(但是我很高兴我知道使用python漂亮打印的东西正确的方法)。