1

我知道:

  • 当使用和 a (而不是)安装SIGSEGV信号处理程序时,信号处理程序会接收 a ,其中的是发生故障的地址。sigactionsa_sigactionsa_handlersiginfo_t*si_addr

  • 使用ucontext_t我们可以检查寄存器的值,例如指令指针,尽管不是以独立于平台的方式(Linux 信号处理。如何获取中断指令的地址?)。

我的问题:我们还能知道哪个寄存器导致了错误吗?鉴于我们没有内存到内存的移动,这应该只有一个寄存器(毕竟也只有一个si_addr)。当然,我可以检查所有寄存器并搜索si_addr,但可能不止一个匹配项。

我会对不独立于平台的解决方案感到非常满意。

4

1 回答 1

2

加载/存储地址可能不在任何单个寄存器中;它可能是寻址模式之类的结果[rdi + rax*4 + 100]

除了像普通人一样在调试器下运行程序以首先捕获故障之外,没有简单的解决方案可以打印完整的调试器。或者让它生成一个核心转储供您离线分析,如果您需要调试其他人系统上发生的崩溃。

Linux 内核选择转储从故障代码地址开始的指令字节(或者实际上在它之前的某个位置作为上下文),以及所有寄存器的内容。可以在事后从崩溃日志中进行反汇编以查看错误指令,同时查看寄存器内容,而无需在内核本身中包含反汇编程序。请参阅Linux 内核崩溃消息中的“代码”是什么?有关 Linux 所做的示例,以及手动将其分开而不是使用decodecode.

于 2020-07-02T21:23:55.100 回答