C SIGSEGV Handler & Mprotect
handler, mprotect, segmentation-fault, signals
Solution
You have to use `sigaction` with `SA_SIGINFO` instead of `signal` to establish your handler, and then you will get called back with useful information in a `siginfo_t`, including `si_addr`.
`si_addr`, as explained in `sigaction`(2), will contain the address. As for the length, well, you're out of luck unless you're willing to parse instructions. Best you can do is take action for the page reported in `si_addr`, and then if that's not enough, you'll get another signal soon enough. At least, that's how we did things in ObjectStore.
Problem
I'm constructing a program which uses mprotect() to restrict a block of memory from accessing. When the memory is requested, a SIGSEGV is thrown which I listen for using a signal() call. Once the SIGSEGV has been detected, I need to somehow access the pointer to the memory that was requested (that threw the fault) and the size of the segment requested. Is this possible? ``` 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); } ``` Additionally, is there a way to determine the level of mprotect() a block of memory is currently assigned (PROT_NONE,PROT_READ, etc..)?