diff options
author | Valery Ushakov <uwe@stderr.spb.ru> | 2017-09-10 21:45:09 +0300 |
---|---|---|
committer | Valery Ushakov <uwe@stderr.spb.ru> | 2017-09-10 21:45:09 +0300 |
commit | bbdfd52b59f74b1228961d07e13fc4d83969de58 (patch) | |
tree | cf8fe8615a8a79c35c65ac069b3663b91dbead6f | |
parent | 8eba7b79fe0fd83319cc590b9f4a6c480863fd1b (diff) |
Use SA_SIGINFO to report pc in error messages. Copied from Linux.
-rw-r--r-- | emu/NetBSD/os.c | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/emu/NetBSD/os.c b/emu/NetBSD/os.c index 34526088..3aa95975 100644 --- a/emu/NetBSD/os.c +++ b/emu/NetBSD/os.c @@ -13,6 +13,8 @@ #include "fns.h" #include "error.h" +#include "raise.h" + /* For dynamic linking init/fini code that needs malloc */ void (*coherence)(void) = nofence; @@ -31,50 +33,49 @@ int gidnobody = -1; int uidnobody = -1; static struct termios tinit; -/* - * TO DO: - * To get pc on trap, use sigaction instead of signal and - * examine its siginfo structure - */ - -/* static void -diserr(char *s, int pc) +sysfault(char *what, void *addr) { - char buf[ERRMAX]; + char buf[64]; - snprint(buf, sizeof(buf), "%s: pc=0x%lux", s, pc); + snprint(buf, sizeof(buf), "sys: %s%#p", what, addr); disfault(nil, buf); } -*/ static void -trapILL(int signo) +trapILL(int signo, siginfo_t *si, void *a) { USED(signo); - disfault(nil, "Illegal instruction"); + USED(a); + sysfault("illegal instruction pc=", si->si_addr); } -static void -trapBUS(int signo) +static int +isnilref(siginfo_t *si) { - USED(signo); - disfault(nil, "Bus error"); + return si != 0 && (si->si_addr == (void*)~(uintptr_t)0 || (uintptr_t)si->si_addr < 512); } static void -trapSEGV(int signo) +trapmemref(int signo, siginfo_t *si, void *a) { - USED(signo); - disfault(nil, "Segmentation violation"); + USED(a); /* ucontext_t*, could fetch pc in machine-dependent way */ + if(isnilref(si)) + disfault(nil, exNilref); + else if(signo == SIGBUS) + sysfault("bad address addr=", si->si_addr); /* eg, misaligned */ + else + sysfault("segmentation violation addr=", si->si_addr); } static void -trapFPE(int signo) +trapFPE(int signo, siginfo_t *si, void *a) { char buf[64]; + USED(signo); - snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux", getfsr()); + USED(a); + snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux pc=%#p", getfsr(), si->si_addr); disfault(nil, buf); } @@ -187,14 +188,19 @@ libinit(char *imod) signal(SIGINT, cleanexit); if(sflag == 0) { - act.sa_handler = trapBUS; - sigaction(SIGBUS, &act, nil); - act.sa_handler = trapILL; + act.sa_flags = SA_SIGINFO; + + act.sa_sigaction = trapILL; sigaction(SIGILL, &act, nil); - act.sa_handler = trapSEGV; - sigaction(SIGSEGV, &act, nil); - act.sa_handler = trapFPE; + + act.sa_sigaction = trapFPE; sigaction(SIGFPE, &act, nil); + + act.sa_sigaction = trapmemref; + sigaction(SIGBUS, &act, nil); + sigaction(SIGSEGV, &act, nil); + + act.sa_flags = 0; } p = newproc(); |