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 {
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");
......
......@@ -138,15 +138,20 @@ typedef struct 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 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");
......
......@@ -86,3 +86,33 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
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 @@
#include "runtime.h"
int32 debug = 0;
int32 panicking = 0;
void
sys·panicl(int32 lno)
......@@ -19,7 +20,8 @@ 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);
}
......
......@@ -207,6 +207,7 @@ M* allm;
G* allg;
int32 goidgen;
extern int32 gomaxprocs;
extern int32 panicking;
/*
* common functions and data
......@@ -236,6 +237,7 @@ uint32 cmpstring(string, string);
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);
......
......@@ -9,7 +9,7 @@ static struct SigTab sigtab[] = {
/* 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",
......
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