这取决于。在某些处理器上,例如GDB 需要x86_64
正确的展开描述符才能正确展开堆栈。在这样的机器上,用不匹配的 libc 分析 coredump 可能会产生完全的垃圾。
您不需要 libc 的调试符号来获取堆栈跟踪。如果没有调试符号,您将无法获得文件和行号,但您应该获得正确的函数名称(除非发生内联)。
您问题的前提是错误的-调试符号与此无关。在 C1 上生成 coredump 时,在 C2 上分析 coredump 的“正确”方法是拥有 C1 库的副本(例如/tmp/C1/lib/...
)并指示 GDB 使用该副本而不是安装libc
C2
(gdb) set solib-absolute-prefix /tmp/C1
命令。
注意:在将内核加载到 GDB 之前,上述设置必须生效。这个:
gdb exe core
(gdb) set solib-absolute-prefix /tmp/C1
将不起作用(在设置生效之前读取核心)。
这是正确的方法:
gdb exe
(gdb) set solib-absolute-prefix /tmp/C1
(gdb) core core
(我试图在网上找到对此的参考,但没有)。
什么是展开描述符?
当代码在没有帧指针的情况下编译时需要展开描述符(优化模式下 x86_64 的默认设置)。此类代码不保存%rbp 寄存器,因此需要告诉 GDB 如何从当前帧“后退”到调用者帧(此过程也称为堆栈展开)。
为什么 C1 的 libc.so 不包含在核心中?
核心文件通常只包含程序地址空间的可写段的内容。通常不需要只读段(可执行代码和展开描述符所在的位置)——您可以直接从磁盘上的 libc.so 读取它们。
除了在 C2 上分析 C1 的核心时这不起作用!
一些(但不是全部)操作系统允许配置“完整核心转储”,操作系统也将转储只读映射,这样您就可以在任何机器上分析核心。