使用GDB解开已知的堆栈和指令指针

时间:2018-02-21 18:04:10

标签: gdb coredump postmortem-debugging

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

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

有没有办法使用GDB / LLDB代替在线程上显示堆栈,只是解除已知SP / IP的回溯?

2 个答案:

答案 0 :(得分:1)

  

有没有办法使用GDB / LLDB代替在线程上显示堆栈,只是解除已知SP / IP的回溯?

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

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

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

如果你的二进制文件是用帧指针构建的(这不是优化版本中x86_64的默认值),那么这就容易多了:你只需要恢复RBP然后跟随帧指针链

答案 1 :(得分:0)

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

我写了一个有关如何完成此工作的小教程:

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