]> Cypherpunks repositories - gostls13.git/commitdiff
clean stack trace code.
authorRuss Cox <rsc@golang.org>
Wed, 3 Dec 2008 22:20:23 +0000 (14:20 -0800)
committerRuss Cox <rsc@golang.org>
Wed, 3 Dec 2008 22:20:23 +0000 (14:20 -0800)
format is unchanged but shows all frames
(old loop stopped one frame early).

wreck=; 6.out
cannot convert type *main.S·interface2 to interface main.I·interface2: missing method Foo
throw: interface conversion
SIGSEGV: segmentation violation
Faulting address: 0x0
pc: 0x256d

throw+0x46 /home/rsc/go/src/runtime/runtime.c:68
throw(0x863a, 0x0)
hashmap+0x188 /home/rsc/go/src/runtime/iface.c:167
hashmap(0x8760, 0x0, 0x85b0, 0x0, 0x0, ...)
sys·ifaceT2I+0xa8 /home/rsc/go/src/runtime/iface.c:201
sys·ifaceT2I(0x8760, 0x0, 0x85b0, 0x0, 0x0, ...)
main·main+0x4e /home/rsc/go/src/runtime/rt0_amd64_darwin.s:87
main·main()
mainstart+0xf /home/rsc/go/src/runtime/rt0_amd64.s:70
mainstart()
sys·goexit /home/rsc/go/src/runtime/proc.c:110
sys·goexit()

R=r
DELTA=44  (5 added, 15 deleted, 24 changed)
OCL=20358
CL=20368

src/runtime/rt2_amd64.c

index fd40cefefed1c52bc197f38c0e7b34e7b3f5ff1e..9c8436f1778c46dbb87c1ae68efa2be5409e6387 100644 (file)
@@ -9,64 +9,49 @@ extern int32  debug;
 extern uint8 end;
 
 void
-traceback(uint8 *pc, uint8 *sp, void* r15)
+traceback(byte *pc0, byte *sp, G *g)
 {
-       uint8* callpc;
-       int32 counter;
-       int32 i;
-       string name;
+       Stktop *stk;
+       uint64 pc;
+       int32 i, n;
        Func *f;
-       G g;
-       Stktop *stktop;
 
-       // store local copy of per-process data block that we can write as we unwind
-       mcpy((byte*)&g, (byte*)r15, sizeof(G));
+       pc = (uint64)pc0;
 
-       // if the PC is zero, it's probably due to a nil function pointer.
-       // pop the failed frame.
-       if(pc == nil) {
-               pc = ((uint8**)sp)[0];
+       // If the PC is zero, it's likely a nil function call.
+       // Start in the caller's frame.
+       if(pc == 0) {
+               pc = *(uint64*)sp;
                sp += 8;
        }
 
-       counter = 0;
-       for(;;){
-               callpc = pc;
-               if((uint8*)retfromnewstack == pc) {
-                       // call site is retfromnewstack(); pop to earlier stack block to get true caller
-                       stktop = (Stktop*)g.stackbase;
-                       g.stackbase = stktop->oldbase;
-                       g.stackguard = stktop->oldguard;
-                       sp = stktop->oldsp;
-                       pc = ((uint8**)sp)[1];
-                       sp += 16;  // two irrelevant calls on stack - morestack, plus the call morestack made
-                       continue;
+       stk = (Stktop*)g->stackbase;
+       for(n=0; n<100; n++) {
+               while(pc == (uint64)retfromnewstack) {
+                       // pop to earlier stack block
+                       sp = stk->oldsp;
+                       stk = (Stktop*)stk->oldbase;
+                       pc = *(uint64*)(sp+8);
+                       sp += 16;       // two irrelevant calls on stack: morestack plus its call
                }
-               f = findfunc((uint64)callpc);
+               f = findfunc(pc);
                if(f == nil) {
-                       printf("%p unknown pc\n", callpc);
+                       printf("%p unknown pc\n", pc);
                        return;
                }
-               name = f->name;
                if(f->frame < 8)        // assembly funcs say 0 but lie
                        sp += 8;
                else
                        sp += f->frame;
-               if(counter++ > 100){
-                       prints("stack trace terminated\n");
-                       break;
-               }
-               if((pc = ((uint8**)sp)[-1]) <= (uint8*)0x1000)
-                       break;
 
                // print this frame
                //      main+0xf /home/rsc/go/src/runtime/x.go:23
                //              main(0x1, 0x2, 0x3)
-               printf("%S", name);
-               if((uint64)callpc > f->entry)
-                       printf("+%X", (uint64)callpc - f->entry);
-               printf(" %S:%d\n", f->src, funcline(f, (uint64)callpc-1));      // -1 to get to CALL instr.
-               printf("\t%S(", name);
+               printf("%S", f->name);
+               if(pc > f->entry)
+                       printf("+%X", pc - f->entry);
+               printf(" %S:%d\n", f->src, funcline(f, pc-1));  // -1 to get to CALL instr.
+               printf("\t%S(", f->name);
                for(i = 0; i < f->args; i++) {
                        if(i != 0)
                                prints(", ");
@@ -77,5 +62,10 @@ traceback(uint8 *pc, uint8 *sp, void* r15)
                        }
                }
                prints(")\n");
+
+               pc = *(uint64*)(sp-8);
+               if(pc <= 0x1000)
+                       return;
        }
+       prints("...\n");
 }