当我用Java编写代码时,我使用Eclipse中嵌入的调试器。在这个上下文中可视化对象时,调试器会自动调用toString()函数,这个函数在我探索程序状态时非常方便快速可视化。
现在,当我在C中工作时,我使用emacs + gdb进行调试,但是我没有设法找到/重新创建用于可视化复杂C结构的等效功能(即调用特定的打印功能)。当然没有通用的toString()方法,但无论如何我经常在某处为我的结构实现打印功能。
但是当我想在gdb中可视化某些东西时,我必须从gdb手动调用这些打印函数p my_print_function(my_struct_pointer)
,效率非常低(必须记住它的名字,正确输入,而且标准输出可能在另一个窗口......)。
我想要的是配置gdb说“当在结构指针类型 T 上调用gdb打印函数时,自动调用用户定义的打印函数 f ...“。有没有办法做到这一点 ?提前谢谢。
答案 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漂亮打印的东西正确的方法)。