我在Linux x64上有一个核心转储。在某些时候SIGSEGV发生了,不幸的是应用程序处理了这个信号(但最终仍然失败了)。因此核心转储不直接包含原始SIGSEGV的帧。
我能够确定失败指令的SP和IP(以及其他寄存器)。基本上我有完整的ucontext结构。
有没有办法使用GDB / LLDB代替在线程上显示堆栈,只是解除已知SP / IP的回溯?
答案 0 :(得分:1)
有没有办法使用GDB / LLDB代替在线程上显示堆栈,只是解除已知SP / IP的回溯?
RSP
和RIP
是必需的,但还不够:您还需要知道崩溃时堆栈的内容
从您的描述中可以看出,您的信号处理程序试图从此崩溃中恢复(可能是siglongjmp
),在这种情况下,堆栈已展开并且其内容可能已消失。
情况并非如此,您可以手动展开堆栈,但(据我所知)GDB没有任何支持这样做。您必须检查展开描述符(readelf -wf a.out
)并手动执行必要的寄存器恢复操作。
如果你的二进制文件是用帧指针构建的(这不是优化版本中x86_64
的默认值),那么这就容易多了:你只需要恢复RBP
然后跟随帧指针链
答案 1 :(得分:0)
我上周遇到了同样的问题。我在没有主要可执行文件或支持库的情况下发生了崩溃,因此gdb无法显示我需要调试的库的回溯记录。我最终通过使用magic_elf修改核心文件来修复它,以便将该线程中的RSP和RIP设置为segfault处理程序报告的寄存器。
我写了一个有关如何完成此工作的小教程: