Commit 6e8dbc20 authored by Rob Pike's avatar Rob Pike

- catch trace traps

- disassemble the instructions in a trace trap to see if it's a run-time trap
- if so, print relevant info
- avoid double-printing traceback on panic

R=ken,rsc
DELTA=66  (50 added, 7 deleted, 9 changed)
OCL=15199
CL=15224
parent 96b90649
...@@ -130,20 +130,24 @@ typedef struct sigaction { ...@@ -130,20 +130,24 @@ typedef struct sigaction {
int32 sa_flags; /* see signal options below */ int32 sa_flags; /* see signal options below */
} sigaction; } sigaction;
void void
sighandler(int32 sig, siginfo *info, void *context) sighandler(int32 sig, siginfo *info, void *context)
{ {
if(sig < 0 || sig >= NSIG){ if(panicking) // traceback already printed
prints("Signal "); sys·exit(2);
sys·printint(sig);
}else{
prints(sigtab[sig].name);
}
_STRUCT_MCONTEXT64 *uc_mcontext = get_uc_mcontext(context); _STRUCT_MCONTEXT64 *uc_mcontext = get_uc_mcontext(context);
_STRUCT_X86_THREAD_STATE64 *ss = get___ss(uc_mcontext); _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("\nFaulting address: 0x"); sys·printpointer(info->si_addr);
prints("\npc: 0x"); sys·printpointer((void *)ss->__rip); prints("\npc: 0x"); sys·printpointer((void *)ss->__rip);
prints("\n\n"); prints("\n\n");
......
...@@ -138,15 +138,20 @@ typedef struct sigaction { ...@@ -138,15 +138,20 @@ typedef struct sigaction {
void void
sighandler(int32 sig, siginfo* info, void** context) sighandler(int32 sig, siginfo* info, void** context)
{ {
if(sig < 0 || sig >= NSIG){ if(panicking) // traceback already printed
prints("Signal "); sys·exit(2);
sys·printint(sig);
}else{
prints(sigtab[sig].name);
}
struct sigcontext *sc = &(((struct ucontext *)context)->uc_mcontext); 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("\nFaulting address: 0x"); sys·printpointer(info->si_addr);
prints("\npc: 0x"); sys·printpointer((void *)sc->rip); prints("\npc: 0x"); sys·printpointer((void *)sc->rip);
prints("\n\n"); prints("\n\n");
......
...@@ -86,3 +86,33 @@ traceback(uint8 *pc, uint8 *sp, void* r15) ...@@ -86,3 +86,33 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
prints(", ...)\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;
}
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "runtime.h" #include "runtime.h"
int32 debug = 0; int32 debug = 0;
int32 panicking = 0;
void void
sys·panicl(int32 lno) sys·panicl(int32 lno)
...@@ -19,7 +20,8 @@ sys·panicl(int32 lno) ...@@ -19,7 +20,8 @@ sys·panicl(int32 lno)
sp = (uint8*)&lno; sp = (uint8*)&lno;
traceback(sys·getcallerpc(&lno), sp, g); traceback(sys·getcallerpc(&lno), sp, g);
tracebackothers(g); tracebackothers(g);
sys·breakpoint(); panicking = 1;
sys·breakpoint(); // so we can grab it in a debugger
sys·exit(2); sys·exit(2);
} }
......
...@@ -207,6 +207,7 @@ M* allm; ...@@ -207,6 +207,7 @@ M* allm;
G* allg; G* allg;
int32 goidgen; int32 goidgen;
extern int32 gomaxprocs; extern int32 gomaxprocs;
extern int32 panicking;
/* /*
* common functions and data * common functions and data
...@@ -236,6 +237,7 @@ uint32 cmpstring(string, string); ...@@ -236,6 +237,7 @@ uint32 cmpstring(string, string);
void initsig(void); void initsig(void);
void traceback(uint8 *pc, uint8 *sp, G* gp); void traceback(uint8 *pc, uint8 *sp, G* gp);
void tracebackothers(G*); void tracebackothers(G*);
int32 inlinetrap(int32 sig, byte* pc);
int32 open(byte*, int32, ...); int32 open(byte*, int32, ...);
int32 read(int32, void*, int32); int32 read(int32, void*, int32);
int32 write(int32, void*, int32); int32 write(int32, void*, int32);
......
...@@ -9,7 +9,7 @@ static struct SigTab sigtab[] = { ...@@ -9,7 +9,7 @@ static struct SigTab sigtab[] = {
/* 2 */ 0, "SIGINT: interrupt program", /* 2 */ 0, "SIGINT: interrupt program",
/* 3 */ 1, "SIGQUIT: quit program", /* 3 */ 1, "SIGQUIT: quit program",
/* 4 */ 1, "SIGILL: illegal instruction", /* 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", /* 6 */ 1, "SIGABRT: abort program",
/* 7 */ 1, "SIGEMT: emulate instruction executed", /* 7 */ 1, "SIGEMT: emulate instruction executed",
/* 8 */ 1, "SIGFPE: floating-point exception", /* 8 */ 1, "SIGFPE: floating-point exception",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment