我正在构建一个使用 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 等)?

最佳答案

您必须使用 sigactionSA_SIGINFO 而不是 signal 来建立您的处理程序,然后您将收到 siginfo_t 中有用信息的回调,包括 si_addr
si_addr ,如 sigaction (2) 中所述,将包含地址。至于长度,好吧,除非你愿意解析指令,否则你运气不好。您能做的最好的事情是对 si_addr 中报告的页面采取行动,然后如果这还不够,您很快就会收到另一个信号。至少,这就是我们在 ObjectStore 中做事的方式。

关于signals - C SIGSEGV 处理程序和 Mprotect,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2705792/

10-10 13:35