Step 1 : Init a sigaction :
struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); sigemptyset(&act.sa_mask); act.sa_sigaction = handler; act.sa_flags = SA_SIGINFO | SA_ONSTACK;
Step 2 : make this sigaction descriptor SIGSEGV :
sigaction(SIGSEGV, &act, NULL);
(Optional) Step 3 : also process other memory signals:
sigaction(SIGBUS, &act, NULL); sigaction(SIGTRAP, &act, NULL);
Add error handling if necessary
Step 4 Define a handler function:
void handler(int signal, siginfo_t* siginfo, void* uap) { printf("Attempt to access memory at address %p\n", siginfo->si_addr); #ifdef LINUX_64BIT printf("Instruction pointer: %p\n", (((ucontext_t*)uap)->uc_mcontext.gregs[16])); #elif LINUX_32BIT printf("Instruction pointer: %p\n", (((ucontext_t*)uap)->uc_mcontext.gregs[14])); #endif }
You can refer to the manual pages for ucontext_t and siginfo_t for more interesting data that your handler can extract.
source share