qemu/tests/testsig.c
bellard 9de5e440b9 better signal/exception support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@42 c046a42c-6fe2-441c-8c8c-71466251a162
2003-03-23 16:49:39 +00:00

98 lines
2.4 KiB
C

#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)
{
printf("alarm signal=%d\n", 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(i = 0;i < 2; i++) {
sleep(1);
}
return 0;
}