远程事后coredump分析,没有共享系统库的确切调试符号

时间:2010-12-01 22:54:41

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

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

所以:

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

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

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

1 个答案:

答案 0 :(得分:13)

  1. 这取决于。在某些处理器上,例如x86_64,GDB需要正确unwind descriptors才能正确展开堆栈。在这样的机器上,用不匹配的libc分析coredump可能会产生完全垃圾。

  2. libc不需要调试符号来获取堆栈跟踪。如果没有调试符号,您将无法获得文件和行号,但是您应该获得正确的函数名称(除非在进行内联时)。

  3. 你的问题的前提是错误的 - 调试符号与此无关。在C1上生成coredump时,分析C2上coredump的“正确”方法是获得C1的库的副本(例如/tmp/C1/lib/...)并指示GDB使用该副本而不是C2的已安装{{ 1}}与

    libc

  4. 命令。

    注意:在将核心加载到GDB之前,上面的设置必须才能生效。这样:

    (gdb) set solib-absolute-prefix /tmp/C1

    不起作用(在设置生效之前读取核心。)

    这是正确的方法:

    gdb exe core
    (gdb) set solib-absolute-prefix /tmp/C1
    

    (我试图在网上找到对此的引用,但没有)。

    什么是展开描述符?

    在没有帧指针的情况下编译代码时需要展开描述符(优化模式下x86_64的默认值)。这样的代码保存%rbp寄存器,因此GDB需要被告知如何从当前帧“退回”到调用者帧(此过程也称为堆栈展开)。

    为什么C1的libc.so不包含在核心中?

    核心文件通常只包含程序地址空间的可写段的内容。通常不需要只读段(可执行代码和展开描述符所在的段) - 您可以直接从磁盘上的libc.so读取它们。

    除非在C2上分析C1的核心时这不起作用!

    一些(但不是全部)操作系统允许用户配置“完整的coredumps”,其中OS也会转储只读映射,因此您可以在任何计算机上分析核心。