int32 sa_flags; /* see signal options below */
} sigaction;
-
void
sighandler(int32 sig, siginfo *info, void *context)
{
- if(sig < 0 || sig >= NSIG){
- prints("Signal ");
- sys·printint(sig);
- }else{
- prints(sigtab[sig].name);
- }
+ if(panicking) // traceback already printed
+ sys·exit(2);
_STRUCT_MCONTEXT64 *uc_mcontext = get_uc_mcontext(context);
_STRUCT_X86_THREAD_STATE64 *ss = get___ss(uc_mcontext);
+ if(!inlinetrap(sig, (byte *)ss->__rip)) {
+ if(sig < 0 || sig >= NSIG){
+ prints("Signal ");
+ sys·printint(sig);
+ }else{
+ prints(sigtab[sig].name);
+ }
+ }
+
prints("\nFaulting address: 0x"); sys·printpointer(info->si_addr);
prints("\npc: 0x"); sys·printpointer((void *)ss->__rip);
prints("\n\n");
void
sighandler(int32 sig, siginfo* info, void** context)
{
- if(sig < 0 || sig >= NSIG){
- prints("Signal ");
- sys·printint(sig);
- }else{
- prints(sigtab[sig].name);
- }
+ if(panicking) // traceback already printed
+ sys·exit(2);
struct sigcontext *sc = &(((struct ucontext *)context)->uc_mcontext);
+ if(!inlinetrap(sig, (byte *)sc->rip)) {
+ if(sig < 0 || sig >= NSIG){
+ prints("Signal ");
+ sys·printint(sig);
+ }else{
+ prints(sigtab[sig].name);
+ }
+ }
+
prints("\nFaulting address: 0x"); sys·printpointer(info->si_addr);
prints("\npc: 0x"); sys·printpointer((void *)sc->rip);
prints("\n\n");
prints(", ...)\n");
}
}
+
+/*
+ * For trace traps, disassemble instruction to see if it's INTB of known type.
+ */
+int32
+inlinetrap(int32 sig, byte* pc)
+{
+ extern void etext();
+ extern void _rt0_amd64_darwin();
+
+ if(sig != 5) /* SIGTRAP */
+ return 0;
+ if(pc-2 < (byte*)_rt0_amd64_darwin || pc >= (byte*)etext)
+ return 0;
+ if(pc[-2] != 0xcd) /* INTB */
+ return 0;
+ switch(pc[-1]) {
+ case 5:
+ prints("\nTRAP: array out of bounds\n");
+ break;
+ case 6:
+ prints("\nTRAP: leaving function with returning a value\n");
+ break;
+ default:
+ prints("\nTRAP: unknown run-time trap ");
+ sys·printint(pc[-1]);
+ prints("\n");
+ }
+ return 1;
+}
#include "runtime.h"
int32 debug = 0;
+int32 panicking = 0;
void
sys·panicl(int32 lno)
sp = (uint8*)&lno;
traceback(sys·getcallerpc(&lno), sp, g);
tracebackothers(g);
- sys·breakpoint();
+ panicking = 1;
+ sys·breakpoint(); // so we can grab it in a debugger
sys·exit(2);
}
G* allg;
int32 goidgen;
extern int32 gomaxprocs;
+extern int32 panicking;
/*
* common functions and data
void initsig(void);
void traceback(uint8 *pc, uint8 *sp, G* gp);
void tracebackothers(G*);
+int32 inlinetrap(int32 sig, byte* pc);
int32 open(byte*, int32, ...);
int32 read(int32, void*, int32);
int32 write(int32, void*, int32);
/* 2 */ 0, "SIGINT: interrupt program",
/* 3 */ 1, "SIGQUIT: quit program",
/* 4 */ 1, "SIGILL: illegal instruction",
- /* 5 */ 0, "SIGTRAP: trace trap", /* uncaught; used by panic and signal handler */
+ /* 5 */ 1, "SIGTRAP: trace trap", /* used by panic and array out of bounds, etc. */
/* 6 */ 1, "SIGABRT: abort program",
/* 7 */ 1, "SIGEMT: emulate instruction executed",
/* 8 */ 1, "SIGFPE: floating-point exception",