mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 16:53:55 -06:00
better signal/exception support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@42 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
66fb9763af
commit
9de5e440b9
15 changed files with 644 additions and 208 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue