没有共享系统库的精确调试符号的远程事后分析 coredump 分析
Posted
技术标签:
【中文标题】没有共享系统库的精确调试符号的远程事后分析 coredump 分析【英文标题】:Remote Post-mortem coredump analysis without having exact debug symbols for shared system libraries 【发布时间】:2011-05-18 19:35:36 【问题描述】:您通常如何解决这个问题?想象一下,一个线程在 Computer1 上的 libc 代码(这是一个系统共享库)内崩溃,然后生成一个 coredump。但是将在其上分析此 coredump 的 Computer2 可能具有不同版本的 libc。
所以:
在远程计算机上拥有相同的共享库有多重要? gdb 会在 Computer2 上没有完全相同版本的 libc 的情况下正确重建堆栈跟踪吗?
为 libc 提供正确的调试符号有多重要? gdb 会在 Computer2 上没有完全相同的调试符号的情况下正确重建堆栈跟踪吗?
对于共享系统库,避免这种调试符号不匹配问题的“正确”方法是什么?对我来说,似乎没有单一的解决方案可以优雅地解决这个问题?也许有人可以分享他的经验?
【问题讨论】:
【参考方案1】:视情况而定。在某些处理器上,例如x86_64
,GDB 需要正确的unwind descriptors 才能正确展开堆栈。在这样的机器上,用不匹配的 libc 分析 coredump 可能会产生完全的垃圾。
您不需要 libc 的调试符号来获取堆栈跟踪。如果没有调试符号,您将无法获得文件和行号,但您应该获得正确的函数名称(除非发生内联)。
您问题的前提是错误的-调试符号与此无关。当在 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 的核心时这不起作用!
一些(但不是全部)操作系统允许配置“完整核心转储”,操作系统也会在其中转储只读映射,这样您就可以在任何机器上分析核心。
【讨论】:
1.您能否解释一下“正确的展开描述符”一词-您指的是被压入堆栈的 SP 和 BP 寄存器吗? 2. coredump生成时所有的共享库也包含在coredump中,因为它基本上是内存转储?那么为什么 GDB 需要有 libc.so 文件,而它可以使用 coredump 中的 libc 呢? 我已经回答了您的其他问题(尽我所能)。 谢谢 - 答案非常好!我仍然很好奇在哪里可以找到有关“展开描述符如何工作”的更多信息......以上是关于没有共享系统库的精确调试符号的远程事后分析 coredump 分析的主要内容,如果未能解决你的问题,请参考以下文章
在Eclipse中调试时如何查看android SDK系统库的符号?