Gdb 远程事后coredump分析,无需共享系统库的精确调试符号

Gdb 远程事后coredump分析,无需共享系统库的精确调试符号,gdb,shared-libraries,remote-debugging,postmortem-debugging,Gdb,Shared Libraries,Remote Debugging,Postmortem Debugging,你通常如何解决这个问题?假设Computer1上的一个线程在libc代码(系统共享库)中崩溃,然后生成一个coredump。但是用于分析此coredump的计算机2可能具有不同版本的libc 因此: 在远程计算机上拥有相同的共享库有多重要?gdb是否能够在Conputer2上正确地重建stacktrace,而不使用完全相同的libc版本 为libc提供正确的调试符号有多重要?gdb是否会正确地重建stacktrace,而不会在计算机2上使用完全相同的调试符号 对于共享系统库,避免调试符号不匹配问

你通常如何解决这个问题?假设Computer1上的一个线程在libc代码(系统共享库)中崩溃,然后生成一个coredump。但是用于分析此coredump的计算机2可能具有不同版本的libc

因此:

  • 在远程计算机上拥有相同的共享库有多重要?gdb是否能够在Conputer2上正确地重建stacktrace,而不使用完全相同的libc版本

  • 为libc提供正确的调试符号有多重要?gdb是否会正确地重建stacktrace,而不会在计算机2上使用完全相同的调试符号

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

  • 视情况而定。在某些处理器上,如
    x86_64
    ,GDB需要正确的操作才能正确地展开堆栈。在这样的机器上,使用不匹配的libc分析coredump可能会产生完全的垃圾

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

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

    (gdb)设置solib绝对前缀/tmp/C1

  • 指挥部

    注意:在将core加载到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不包含在核心中

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

    但当你在C2上分析C1的核心时,这不起作用


    一些(但不是所有)操作系统允许配置“完整coredumps”,操作系统也会在其中转储只读映射,以便您可以在任何机器上分析core。

    1。您能解释一下“正确的展开描述符”这个术语吗?您指的是堆栈中推入的SP和BP寄存器吗?2.当生成coredump时,所有共享库也包括在coredump中,因为它基本上是内存转储?那么为什么GDB需要libc.So文件,而它可以使用coredump中的libc呢?我已经回答了您的其他问题(尽我所能)。谢谢您-答案非常好!我仍然很好奇在哪里可以找到关于“放松描述符如何工作”的更多信息。。。