訊號
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
// /usr/include/sys/ucontext.h
void segv_handler(int sig, siginfo_t *si, void *context)
{
printf("Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr);
abort();
}
int main() {
struct sigaction act;
/* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */
act.sa_flags = SA_SIGINFO;
/* Use the sa_sigaction field because the handles has two additional parameters */
act.sa_sigaction = segv_handler;
sigemptyset(&act.sa_mask);
/* Register our signal handler. */
sigaction(SIGSEGV, &act, NULL);
/* Trigger segfault */
*(char *) 0 = 0;
}
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void segv_handler(int sig, siginfo_t *si, void *context)
{
fprintf(stderr, "Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr);
if (si->si_code == SEGV_MAPERR)
fprintf(stderr, "Address not mapped to object\n");
else if (si->si_code == SEGV_ACCERR)
fprintf(stderr, "Invalid permissions for mapped object\n");
else
fprintf(stderr, "No such code\n");
exit(1);
}
static void map_readonly(void *addr, long size)
{
unsigned long start, end, page_size;
page_size = getpagesize();
start = (unsigned long)addr;
start &= ~(page_size - 1);
end = (unsigned long)addr + size;
end += page_size - 1;
end &= ~(page_size - 1);
mprotect((void *)start, end - start,
PROT_READ);
}
int main()
{
sigset_t set;
struct sigaction sigact;
char *vaddr = 0;
memset(&sigact, 0, sizeof(sigact));
sigact.sa_flags = SA_SIGINFO;
sigact.sa_sigaction = segv_handler;
sigaction(SIGSEGV, &sigact, NULL);
sigemptyset(&set);
sigaddset(&set, SIGSEGV);
//*vaddr = 'a'; // SEGV_MAPERR
char *vaddr2 = (char *)malloc(4);
map_readonly(vaddr2, 4);
*vaddr2 = 'a'; // SEGV_ACCERR
}
其它
外部連結