GDB:当没有可用的名称符号时如何打印函数参数值

Posted

技术标签:

【中文标题】GDB:当没有可用的名称符号时如何打印函数参数值【英文标题】:GDB: how to print function argument values when no name symbols available 【发布时间】:2015-04-12 12:06:28 【问题描述】:

我正在检查核心转储,并且需要在仅知道函数类型的情况下打印函数参数值(无参数名称符号):

(gdb) frame 7
#7  0x00007f201a269e82 in f1(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char*, int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*) () from /usr/lib64/libsome.so
(gdb) info args
No symbol table info available.
(gdb) info f
Stack level 7, frame at 0x7f200ebf9e50:
 rip = 0x7f201a269e82
    in f1(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char*, int, std::basic_string<char, std::char_traits<char>, std::allocator<char> >*); saved rip 0x7f201b430905
 called by frame at 0x7f200ebfa1c0, caller of frame at 0x7f200ebf9e00
 Arglist at 0x7f200ebf9df8, args:
 Locals at 0x7f200ebf9df8, Previous frame's sp is 0x7f200ebf9e50
 Saved registers:
  rbx at 0x7f200ebf9e28, rbp at 0x7f200ebf9e30, r12 at 0x7f200ebf9e38, r13 at 0x7f200ebf9e40, rip at 0x7f200ebf9e48

具体来说,我需要知道第一个参数 (std::string) 和最后一个参数 (std::string*) 中的内容。 这个框架中的 arglistlocals 都指向同一个地址...

【问题讨论】:

尝试解散这个函数。也许你会得到一些关于函数参数的信息。 【参考方案1】:

没有简单的方法可以做到这一点。

您需要做的是为您的平台查找 ABI,然后使用它来理解参数传递约定。这并不总是那么容易,但可以做到。这将告诉您如何找到参数,无论它们是在寄存器中还是在内存中;然后您可以使用强制转换为适当的类型来打印它们。

当然,如果您没有调试信息,转换也可能很困难。虽然有一个技巧:使用 -g 编译一个具有您需要的类型的虚拟文件,然后将 symbol-file 编译到 gdb 中以访问这些类型。这当然有一些注意事项,您必须使用正确的编译器和库版本、正确的编译器目标和 ABI 更改标志等。

提前计划并始终在某个地方提供调试信息真的要好得多。这对您现在没有帮助,但将来可以。能够发布程序但保留调试信息以供以后使用基本上是发明拆分调试信息的原因。

另外,值得注意的是,gdb frame 输出自刺痛时代以来并没有太大变化,而刺痛时代早已一去不复返了。我认为“arglist”和“locals”信息对于 DWARF 和现代 ABI 来说确实毫无意义。有一个关于修复此问题的 gdb 错误。

【讨论】:

以上是关于GDB:当没有可用的名称符号时如何打印函数参数值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux 架构上即时列出 C 代码中可用的所有函数/符号?

使用 GDB 在堆栈上打印符号

打印定义给定符号的库的名称

如何 gdb 如何打印一个地址中的内容

在 x86 上使用 GDB 而不调试符号?

堆栈跟踪中没有函数名称,GDB,但出现在LLDB中[重复]