From: Russ Cox Date: Wed, 26 Nov 2008 01:17:54 +0000 (-0800) Subject: new stacktrace format X-Git-Tag: weekly.2009-11-06~2601 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d040d268636cd6ee347c7e3138af508b2d95fbec;p=gostls13.git new stacktrace format sys·gosched+0x25 /home/rsc/go/src/runtime/proc.c:477 sys·gosched() chanrecv+0x29e /home/rsc/go/src/runtime/chan.c:277 chanrecv(0x4be80, 0x0, 0x4cf88, 0x0, 0x0, ...) sys·chanrecv1+0x5b /home/rsc/go/src/runtime/chan.c:355 sys·chanrecv1(0x4be80, 0x0) once·Server+0x26 /home/rsc/go/src/lib/strconv/atoi.go:-41 once·Server() the last line is broken (atoi.go:-41) but that's not new. R=r DELTA=46 (19 added, 14 deleted, 13 changed) OCL=20018 CL=20026 --- diff --git a/src/runtime/rt2_amd64.c b/src/runtime/rt2_amd64.c index 3d4ff7cb50..fd40cefefe 100644 --- a/src/runtime/rt2_amd64.c +++ b/src/runtime/rt2_amd64.c @@ -30,7 +30,6 @@ traceback(uint8 *pc, uint8 *sp, void* r15) } counter = 0; - name = gostring((byte*)"panic"); for(;;){ callpc = pc; if((uint8*)retfromnewstack == pc) { @@ -44,10 +43,15 @@ traceback(uint8 *pc, uint8 *sp, void* r15) continue; } f = findfunc((uint64)callpc); - if(f == nil) + if(f == nil) { + printf("%p unknown pc\n", callpc); return; + } name = f->name; - sp += f->frame; + 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; @@ -55,32 +59,23 @@ traceback(uint8 *pc, uint8 *sp, void* r15) if((pc = ((uint8**)sp)[-1]) <= (uint8*)0x1000) break; - /* print this frame */ - prints("0x"); - sys·printpointer(callpc - 1); // -1 to get to CALL instr. - prints("?zi "); - sys·printstring(f->src); - prints(":"); - sys·printint(funcline(f, (uint64)callpc-1)); // -1 to get to CALL instr. - prints("\n"); - prints("\t"); - sys·printstring(name); - prints("("); - for(i = 0; i < 3; i++){ - if(i != 0) - prints(", "); - sys·printint(((uint32*)sp)[i]); - } - prints(", ...)\n"); - prints("\t"); - sys·printstring(name); - prints("("); - for(i = 0; i < 3; i++){ + // 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); + for(i = 0; i < f->args; i++) { if(i != 0) prints(", "); - prints("0x"); - sys·printpointer(((void**)sp)[i]); + sys·printhex(((uint32*)sp)[i]); + if(i >= 4) { + prints(", ..."); + break; + } } - prints(", ...)\n"); + prints(")\n"); } } diff --git a/src/runtime/symtab.c b/src/runtime/symtab.c index 80c49e01a0..9580cad712 100644 --- a/src/runtime/symtab.c +++ b/src/runtime/symtab.c @@ -127,6 +127,16 @@ dofunc(Sym *sym) if(nfunc > 0 && func != nil) func[nfunc-1].frame = sym->value; break; + case 'p': + if(nfunc > 0 && func != nil) { + f = &func[nfunc-1]; + // args counts 32-bit words. + // sym->value is the arg's offset. + // don't know width of this arg, so assume it is 64 bits. + if(f->args < sym->value/4 + 2) + f->args = sym->value/4 + 2; + } + break; case 'f': if(fname == nil) { if(sym->value >= nfname)