From 2b39165f1eabc309bc774f6b1ac7c0ce62270c5d Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 3 Dec 2008 14:20:23 -0800 Subject: [PATCH] clean stack trace code. format is unchanged but shows all frames (old loop stopped one frame early). MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 68 ++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/src/runtime/rt2_amd64.c b/src/runtime/rt2_amd64.c index fd40cefefe..9c8436f177 100644 --- a/src/runtime/rt2_amd64.c +++ b/src/runtime/rt2_amd64.c @@ -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"); } -- 2.48.1