12

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

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

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

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

4

3 回答 3

7

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

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

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

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

也可以ptype struct_var用来打印给定结构的定义

更多信息在这里

于 2013-03-01T15:08:46.587 回答
5

好问题。

是的,我猜有点。似乎 GDB 7 支持用 Python 编写的“漂亮打印机”。不像在实际目标语言中使用已经编写的代码那样方便(在我看来),但也许已经足够好了。

这些是使用漂亮打印机的命令。

于 2013-03-01T15:05:14.177 回答
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 漂亮打印的东西来做到这一点的正确方法)。

于 2013-04-11T10:23:25.140 回答