您通常如何解决这个问题?想象一下,在计算机1上的LIBC代码(是系统共享库)中的线程崩溃,然后生成核心。但是,将分析该核心的计算机2可能具有不同的LIBC版本。

所以:

  1. 在远程计算机上拥有相同的共享库有多重要? GDB是否可以正确重建StackTrace,而不会在Contuper2上具有完全相同的LIBC版本?

  2. 为LIBC拥有正确的调试符号有多重要? GDB是否会在计算机上没有完全相同的调试符号正确重建StackTrace?

  3. 避免共享系统库的此调试符号不匹配问题的“正确”方法是什么?对我来说,似乎没有一个解决方案以优雅的方式解决这个问题?也许有人可以分享他的经验?

有帮助吗?

解决方案

  1. 这取决于。在某些处理器上,例如 x86_64, , 正确的 放松描述符 GDB需要正确放松堆栈所必需。在这样的机器上,用非匹配的LIBC分析Coredump可能会产生完整的垃圾。

  2. 您不需要LIBC的调试符号即可获取堆栈跟踪。如果没有调试符号,您将不会获得文件和行号,但是您应该获得正确的功能名称(除非发生了内联)。

  3. 您的问题的前提是错误的 - 调试符号与此无关。当C1上生产Coredump时,在C2上分析Coredump的“正确”方法是具有C1库的副本(例如 /tmp/C1/lib/...)并指示GDB使用该副本而不是安装C2 libc

    (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核心,否则这是不起作用的!

某些(但不是全部)操作系统允许一个配置“完整核心”,在该操作系统中也可以在其中转储仅读取的映射,因此您可以在任何机器上分析核心。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top