【问题标题】:Remote Post-mortem coredump analysis without having exact debug symbols for shared system libraries没有共享系统库的精确调试符号的远程事后分析 coredump 分析
【发布时间】:2011-05-18 19:35:36
【问题描述】:

您通常如何解决这个问题?想象一下,一个线程在 Computer1 上的 libc 代码(这是一个系统共享库)内崩溃,然后生成一个 coredump。但是将在其上分析此 coredump 的 Computer2 可能具有不同版本的 libc。

所以:

  1. 在远程计算机上拥有相同的共享库有多重要? gdb 会在 Computer2 上没有完全相同版本的 libc 的情况下正确重建堆栈跟踪吗?

  2. 为 libc 提供正确的调试符号有多重要? gdb 会在 Computer2 上没有完全相同的调试符号的情况下正确重建堆栈跟踪吗?

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

【问题讨论】:

    标签: gdb shared-libraries remote-debugging postmortem-debugging


    【解决方案1】:
    1. 视情况而定。在某些处理器上,例如x86_64,GDB 需要正确的unwind descriptors 才能正确展开堆栈。在这样的机器上,用不匹配的 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 的核心时这不起作用!

    一些(但不是全部)操作系统允许配置“完整核心转储”,操作系统也会在其中转储只读映射,这样您就可以在任何机器上分析核心。

    【讨论】:

    • 1.您能否解释一下“正确的展开描述符”一词-您指的是被压入堆栈的 SP 和 BP 寄存器吗? 2. coredump生成时所有的共享库也包含在coredump中,因为它基本上是内存转储?那么为什么 GDB 需要有 libc.so 文件,而它可以使用 coredump 中的 libc 呢?
    • 我已经回答了您的其他问题(尽我所能)。
    • 谢谢 - 答案非常好!我仍然很好奇在哪里可以找到有关“展开描述符如何工作”的更多信息......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 2014-07-09
    相关资源
    最近更新 更多