2

我在 Linux x64 上有一个核心转储。在某些时候 SIGSEGV 发生了,不幸的是应用程序处理了这个信号(但最终还是失败了)。所以核心转储不直接包含原始 SIGSEGV 的帧。

我能够确定失败指令的 SP 和 IP(以及其他寄存器)。基本上我有完整的 ucontext 结构。

有没有办法使用 GDB/LLDB 而不是在线程上显示堆栈只是从已知的 SP/IP 展开回溯?

4

2 回答 2

3

我上周遇到了同样的问题。我在没有主要可执行文件或支持库的情况下发生崩溃,因此 gdb 无法显示我需要调试的库的回溯。我最终通过使用 magic_elf 修改核心文件来修复它,以便将该线程中的 RSP 和 RIP 设置为 segfault 处理程序报告的寄存器。

我写了一个关于如何做到这一点的小教程:

http://www.mikekohn.net/software/core_file_analysis.php

于 2019-05-13T13:25:13.590 回答
2

有没有办法使用 GDB/LLDB 而不是在线程上显示堆栈只是从已知的 SP/IP 展开回溯?

RSPRIP是必要的,但还不够:您还需要知道崩溃时堆栈的内容

从您的描述中听起来,您的信号处理程序试图从这次崩溃中恢复(可能是siglongjmp通过退出),在这种情况下,堆栈已展开并且其内容可能已经消失。

事实并非如此,您也许可以手动展开堆栈,但是(据我所知)GDB 不支持这样做。您必须检查展开描述符 ( readelf -wf a.out) 并手动执行必要的寄存器恢复操作。

如果您的二进制文件是使用帧指针构建的(这不是x86_64优化构建中的默认设置),这会容易得多:您只需要恢复RBP然后遵循帧指针链。

于 2018-02-21T18:16:10.030 回答