]> Cypherpunks repositories - gostls13.git/commitdiff
- catch trace traps
authorRob Pike <r@golang.org>
Fri, 12 Sep 2008 16:44:41 +0000 (09:44 -0700)
committerRob Pike <r@golang.org>
Fri, 12 Sep 2008 16:44:41 +0000 (09:44 -0700)
- 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

src/runtime/rt1_amd64_darwin.c
src/runtime/rt1_amd64_linux.c
src/runtime/rt2_amd64.c
src/runtime/runtime.c
src/runtime/runtime.h
src/runtime/signals.h

index da10508a0e9bf10f7de2a8913aa75f8cd93c9117..49ecb3a0caf004d2190eda5e4a7d3a6d9e9233c0 100644 (file)
@@ -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");
index c14b3385256dc69e55a47e8b34e59c4f574abe87..403b248338661adfe763d0b23c2fd31d28a4eed7 100644 (file)
@@ -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");
index 91bef5434068092b0d4a57c85269ea34a516bfc1..2943ac0d36ab8656971e95f106e05532412731e8 100644 (file)
@@ -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;
+}
index 973fb5bd3c65fa7d5b90e93edc298370a57b20c8..26becc52a5453a02e676b515795d48afa309555a 100644 (file)
@@ -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);
 }
 
index c64e5b37e7dd23af3703ade4276bfb94a34bca57..11d3fdac8ee818e68f77ef2e988d8727869394ba 100644 (file)
@@ -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);
index 5b2776a4385aa39acfc43d01a2c0ee0f084f83d7..475f6752b5099d8d2b118c9cc809aba9f1ecb17b 100644 (file)
@@ -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",