#define _GNU_SOURCE #include #include #include #include #include #include #include jmp_buf jmp_env; void alarm_handler(int sig) { printf("alarm signal=%d\n", sig); alarm(1); } #ifndef REG_EAX #define REG_EAX EAX #define REG_EBX EBX #define REG_ECX ECX #define REG_EDX EDX #define REG_ESI ESI #define REG_EDI EDI #define REG_EBP EBP #define REG_ESP ESP #define REG_EIP EIP #define REG_EFL EFL #endif void dump_regs(struct ucontext *uc) { printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" "EFL=%08x EIP=%08x\n", uc->uc_mcontext.gregs[REG_EAX], uc->uc_mcontext.gregs[REG_EBX], uc->uc_mcontext.gregs[REG_ECX], uc->uc_mcontext.gregs[REG_EDX], uc->uc_mcontext.gregs[REG_ESI], uc->uc_mcontext.gregs[REG_EDI], uc->uc_mcontext.gregs[REG_EBP], uc->uc_mcontext.gregs[REG_ESP], uc->uc_mcontext.gregs[REG_EFL], uc->uc_mcontext.gregs[REG_EIP]); } void sig_handler(int sig, siginfo_t *info, void *puc) { struct ucontext *uc = puc; printf("%s: si_signo=%d si_errno=%d si_code=%d si_addr=0x%08lx\n", strsignal(info->si_signo), info->si_signo, info->si_errno, info->si_code, (unsigned long)info->si_addr); dump_regs(uc); longjmp(jmp_env, 1); } int v1; int main(int argc, char **argv) { struct sigaction act; int i; /* test division by zero reporting */ if (setjmp(jmp_env) == 0) { act.sa_sigaction = sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO | SA_ONESHOT; sigaction(SIGFPE, &act, NULL); /* now divide by zero */ v1 = 0; v1 = 2 / v1; } /* test illegal instruction reporting */ if (setjmp(jmp_env) == 0) { act.sa_sigaction = sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO | SA_ONESHOT; sigaction(SIGILL, &act, NULL); /* now execute an invalid instruction */ asm volatile("ud2"); } /* test SEGV reporting */ if (setjmp(jmp_env) == 0) { act.sa_sigaction = sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO | SA_ONESHOT; sigaction(SIGSEGV, &act, NULL); /* now store in an invalid address */ *(char *)0x1234 = 1; } act.sa_handler = alarm_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); alarm(1); for(i = 0;i < 2; i++) { sleep(1); } return 0; }