diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/testsig.c | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/tests/testsig.c b/tests/testsig.c index 59af54fc8e..d93f42806a 100644 --- a/tests/testsig.c +++ b/tests/testsig.c @@ -1,7 +1,13 @@ +#define _GNU_SOURCE #include <stdlib.h> #include <stdio.h> +#include <string.h> #include <signal.h> #include <unistd.h> +#include <setjmp.h> +#include <sys/ucontext.h> + +jmp_buf jmp_env; void alarm_handler(int sig) { @@ -9,15 +15,82 @@ void alarm_handler(int sig) alarm(1); } +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[EAX], + uc->uc_mcontext.gregs[EBX], + uc->uc_mcontext.gregs[ECX], + uc->uc_mcontext.gregs[EDX], + uc->uc_mcontext.gregs[ESI], + uc->uc_mcontext.gregs[EDI], + uc->uc_mcontext.gregs[EBP], + uc->uc_mcontext.gregs[ESP], + uc->uc_mcontext.gregs[EFL], + uc->uc_mcontext.gregs[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(;;) { + for(i = 0;i < 2; i++) { sleep(1); } return 0; |