我正在构建一个使用 mprotect() 来限制访问内存块的程序。当请求内存时,会抛出一个 SIGSEGV,我使用 signal() 调用来监听它。
检测到 SIGSEGV 后,我需要以某种方式访问指向请求的内存(引发错误)和请求的段的大小的指针。这可能吗?
void fifoSigHandler(){
// Needs to only remove protection from requested block of virtual memory
mprotect(fifoVm,(size_t)fifoVm_size,PROT_WRITE);
printf("Caught Seg Fault");
}
void fifo_init(void* vm, int vm_size, int n_frames, int page_size)
{
fifoVm = vm;
fifoVm_size = vm_size;
fifoFrames = n_frames;
fifoPageSize = page_size;
mprotect(fifoVm,(size_t)fifoVm_size,PROT_NONE);
signal(SIGSEGV, fifoSigHandler);
}
此外,有没有办法确定当前分配的内存块的 mprotect() 级别(PROT_NONE、PROT_READ 等)?
最佳答案
您必须使用 sigaction
和 SA_SIGINFO
而不是 signal
来建立您的处理程序,然后您将收到 siginfo_t
中有用信息的回调,包括 si_addr
。si_addr
,如 sigaction
(2) 中所述,将包含地址。至于长度,好吧,除非你愿意解析指令,否则你运气不好。您能做的最好的事情是对 si_addr
中报告的页面采取行动,然后如果这还不够,您很快就会收到另一个信号。至少,这就是我们在 ObjectStore 中做事的方式。
关于signals - C SIGSEGV 处理程序和 Mprotect,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2705792/