#include #include #include #include #include #include jmp_buf j; int handler(int signum, siginfo_t *info) { printf("sig %d\n", signum); printf("si_signo %d si_errno %d si_code %d\n", info->si_signo, info->si_errno, info->si_code); switch (signum) { case SIGFPE: case SIGBUS: case SIGILL: case SIGSEGV: printf("si_addr %08x", info->si_addr); #ifdef __sparc__ printf(" si_trapno %08x", *(int *)((&info->si_addr)+1)); #endif printf("\n"); break; case SIGCHLD: printf("si_pid %d si_uid %d si_status %d\n", info->si_pid, info->si_uid, info->si_status); printf("si_utime %ld si_stime %ld", info->si_utime, info->si_stime); #ifdef __i386__ printf(" si_uid32 %d", ((unsigned int *)&info->si_stime)[1]); #endif printf("\n"); } siglongjmp(j, 1); } static int zero = 0; double zerod = 0.0; double small = 1e-30; double big = 1e+100; double a, b, c; unsigned long d; int main(void) { struct sigaction sa; static int aa[10]; int status; char *map; map = mmap(NULL, 8192, PROT_READ, MAP_PRIVATE|MAP_ANON, -1, 0); if (map == MAP_FAILED) perror("mmap"); sa.sa_handler = (void *)handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV, &sa, NULL) < 0) perror("sigaction"); if (sigaction(SIGBUS, &sa, NULL) < 0) perror("sigaction"); if (sigaction(SIGFPE, &sa, NULL) < 0) perror("sigaction"); if (sigaction(SIGILL, &sa, NULL) < 0) perror("sigaction"); if (sigaction(SIGCHLD, &sa, NULL) < 0) perror("sigaction"); if (!sigsetjmp(j, 1)) { *(volatile int *)0x4000 = 0; } if (!sigsetjmp(j, 1)) { map[56] = 0; } if (!sigsetjmp(j, 1)) { unsigned long a = (long)&aa[5]; a += 5; *(volatile int *)(a) = 0; } if (!sigsetjmp(j, 1)) { fesetenv(FE_NOMASK_ENV); d = 26 / zero; } if (!sigsetjmp(j, 1)) { fesetenv(FE_NOMASK_ENV); a = 26.0 / zerod; } if (!sigsetjmp(j, 1)) { fesetenv(FE_NOMASK_ENV); b = zerod / zerod; } if (!sigsetjmp(j, 1)) { fesetenv(FE_NOMASK_ENV); c = small + big; } if (!sigsetjmp(j, 1)) { int pid = fork(); if (pid < 0) perror("fork"); if (!pid) { sleep(2); exit(4); } sleep(5); } wait(&status); printf("status %08x\n", status); if (!sigsetjmp(j, 1)) { int pid = fork(); if (pid < 0) perror("fork"); if (!pid) { kill(getpid(), SIGUSR1); exit(4); } sleep(5); } wait(&status); printf("status %08x\n", status); return 0; }