引起外部程序 SIGSEGV 的指令地址

3
我希望获取导致外部程序SIGSEGV的指令地址。我尝试使用ptrace,但是从内核空间(可能是默认信号处理程序?)获取EIP。GDB如何能够获取正确的EIP?
是否有一种方法可以通过某些API使GDB提供此信息?
编辑: 我没有程序的源代码,只有二进制可执行文件。我需要自动化,所以不能简单地在GDB中使用“run”、“info registers”。我想在自己的迷你调试器中实现“info registers” :)
4个回答

3
你可以使用ptrace附加到进程。我在Linux Gazette上找到了一篇文章。
看起来你会想要PTRACE_GETREGS来获取寄存器。你需要查看一些示例代码,如strace,以了解它如何处理信号等。从阅读文档来看,被跟踪的子进程将在每个信号处停止,并且跟踪父进程必须使用wait()等待来自子进程的信号,然后使用PTRACE_CONT命令它继续执行。

0

使用-g编译您的程序,运行gdb <your_app>,输入run,错误将会出现。之后使用info registers并查看rip寄存器。

您可以使用objectdump -D <your_app>获取有关该位置代码的更多信息。


我没有源代码,只有二进制文件。 - karramba

0

在运行外部程序之前,您可以使用ulimit -c unlimited启用核心转储。

然后,在崩溃后,您可以使用gdb /path/to/program corefile检查核心转储文件。

由于它是二进制文件,而且没有使用调试选项进行编译,因此您必须在寄存器和机器代码级别上查看详细信息。


我需要自动化。对我来说最好的解决方案是在我的程序中捕获寄存器值。 - karramba

0

尝试生成核心转储文件,然后使用gdb进行分析。如果你的意思是要让gdb在一次按键中运行所有命令,那么它也可以实现自动化。将你的命令输入到一个文件中,并查看手册中的自定义帮助部分,gdb可以处理预先设定好的命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接