【发布时间】:2013-11-10 22:37:05
【问题描述】:
我正在使用 mprotect 将一些内存页面设置为写保护。当在该内存区域尝试任何写入时,程序会收到一个 SIGSEGV 信号。从信号处理程序中,我知道在哪个内存地址中尝试了写操作,但我不知道如何找出哪条指令导致写保护违规。因此,在信号处理程序内部,我正在考虑读取程序计数器(PC)寄存器以获取错误指令。有没有简单的方法可以做到这一点?
【问题讨论】:
我正在使用 mprotect 将一些内存页面设置为写保护。当在该内存区域尝试任何写入时,程序会收到一个 SIGSEGV 信号。从信号处理程序中,我知道在哪个内存地址中尝试了写操作,但我不知道如何找出哪条指令导致写保护违规。因此,在信号处理程序内部,我正在考虑读取程序计数器(PC)寄存器以获取错误指令。有没有简单的方法可以做到这一点?
【问题讨论】:
如果您使用带有SA_SIGINFO 标志的sigaction 安装信号处理程序,则信号处理程序的第三个参数的类型为void *,但指向ucontext_t 类型的结构,该结构又包含输入mcontext_t。 mcontext_t 的内容是实现定义的,通常是特定于 cpu 架构的,但您可以在此处找到保存的程序计数器。
编译器的内置函数(我认为__builtin_return_address 带有非零参数)以及展开表也可能能够跟踪信号处理程序。虽然这在某些方面更通用(它不是明显特定于 cpu-arch),但我认为它也更脆弱,它是否真正有效可能是特定于 cpu-arch 和 ABI 的。
【讨论】: