Commit 2b39165f authored by Russ Cox's avatar Russ Cox

clean stack trace code.

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