mirror of
https://github.com/golang/go
synced 2024-11-20 07:44:41 -07:00
runtime: record goroutine creation pc and display in traceback
package main func main() { go func() { *(*int)(nil) = 0 }() select{} } panic: runtime error: invalid memory address or nil pointer dereference [signal 0xb code=0x1 addr=0x0 pc=0x1c96] runtime.panic+0xac /Users/rsc/g/go/src/pkg/runtime/proc.c:1083 runtime.panic(0x11bf0, 0xf8400011f0) runtime.panicstring+0xa3 /Users/rsc/g/go/src/pkg/runtime/runtime.c:116 runtime.panicstring(0x29a57, 0x0) runtime.sigpanic+0x144 /Users/rsc/g/go/src/pkg/runtime/darwin/thread.c:470 runtime.sigpanic() main._func_001+0x16 /Users/rsc/g/go/src/pkg/runtime/x.go:188 main._func_001() runtime.goexit /Users/rsc/g/go/src/pkg/runtime/proc.c:150 runtime.goexit() ----- goroutine created by ----- main.main+0x3d /Users/rsc/g/go/src/pkg/runtime/x.go:4 goroutine 1 [4]: runtime.gosched+0x77 /Users/rsc/g/go/src/pkg/runtime/proc.c:598 runtime.gosched() runtime.block+0x27 /Users/rsc/g/go/src/pkg/runtime/chan.c:680 runtime.block() main.main+0x44 /Users/rsc/g/go/src/pkg/runtime/x.go:5 main.main() runtime.mainstart+0xf /Users/rsc/g/go/src/pkg/runtime/amd64/asm.s:77 runtime.mainstart() runtime.goexit /Users/rsc/g/go/src/pkg/runtime/proc.c:150 runtime.goexit() ----- goroutine created by ----- _rt0_amd64+0x8e /Users/rsc/g/go/src/pkg/runtime/amd64/asm.s:64 Fixes #1563. R=r CC=golang-dev https://golang.org/cl/4243046
This commit is contained in:
parent
9733f96b47
commit
324cc3d040
@ -182,6 +182,17 @@ gentraceback(byte *pc0, byte *sp, G *g, int32 skip, uintptr *pcbuf, int32 max)
|
|||||||
sp = fp;
|
sp = fp;
|
||||||
fp = nil;
|
fp = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pcbuf == nil && (pc = g->gopc) != 0 && (f = runtime·findfunc(pc)) != nil) {
|
||||||
|
runtime·printf("----- goroutine created by -----\n%S", f->name);
|
||||||
|
if(pc > f->entry)
|
||||||
|
runtime·printf("+%p", (uintptr)(pc - f->entry));
|
||||||
|
tracepc = pc; // back up to CALL instruction for funcline.
|
||||||
|
if(n > 0 && pc > f->entry)
|
||||||
|
tracepc--;
|
||||||
|
runtime·printf(" %S:%d\n", f->src, runtime·funcline(f, tracepc));
|
||||||
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +175,17 @@ gentraceback(byte *pc0, byte *sp, byte *lr0, G *g, int32 skip, uintptr *pcbuf, i
|
|||||||
if(f->entry == (uintptr)runtime·deferproc || f->entry == (uintptr)runtime·newproc)
|
if(f->entry == (uintptr)runtime·deferproc || f->entry == (uintptr)runtime·newproc)
|
||||||
sp += 12;
|
sp += 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pcbuf == nil && (pc = g->gopc) != 0 && (f = runtime·findfunc(pc)) != nil) {
|
||||||
|
runtime·printf("----- goroutine created by -----\n%S", f->name);
|
||||||
|
if(pc > f->entry)
|
||||||
|
runtime·printf("+%p", (uintptr)(pc - f->entry));
|
||||||
|
tracepc = pc; // back up to CALL instruction for funcline.
|
||||||
|
if(n > 0 && pc > f->entry)
|
||||||
|
tracepc -= sizeof(uintptr);
|
||||||
|
runtime·printf(" %S:%d\n", f->src, runtime·funcline(f, tracepc));
|
||||||
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +585,7 @@ runtime·gc(int32 force)
|
|||||||
if(fp != nil) {
|
if(fp != nil) {
|
||||||
// kick off or wake up goroutine to run queued finalizers
|
// kick off or wake up goroutine to run queued finalizers
|
||||||
if(fing == nil)
|
if(fing == nil)
|
||||||
fing = runtime·newproc1((byte*)runfinq, nil, 0, 0);
|
fing = runtime·newproc1((byte*)runfinq, nil, 0, 0, runtime·gc);
|
||||||
else if(fingwait) {
|
else if(fingwait) {
|
||||||
fingwait = 0;
|
fingwait = 0;
|
||||||
runtime·ready(fing);
|
runtime·ready(fing);
|
||||||
|
@ -884,11 +884,11 @@ runtime·newproc(int32 siz, byte* fn, ...)
|
|||||||
argp = (byte*)(&fn+2); // skip caller's saved LR
|
argp = (byte*)(&fn+2); // skip caller's saved LR
|
||||||
else
|
else
|
||||||
argp = (byte*)(&fn+1);
|
argp = (byte*)(&fn+1);
|
||||||
runtime·newproc1(fn, argp, siz, 0);
|
runtime·newproc1(fn, argp, siz, 0, runtime·getcallerpc(&siz));
|
||||||
}
|
}
|
||||||
|
|
||||||
G*
|
G*
|
||||||
runtime·newproc1(byte *fn, byte *argp, int32 narg, int32 nret)
|
runtime·newproc1(byte *fn, byte *argp, int32 narg, int32 nret, void *callerpc)
|
||||||
{
|
{
|
||||||
byte *sp;
|
byte *sp;
|
||||||
G *newg;
|
G *newg;
|
||||||
@ -926,6 +926,7 @@ runtime·newproc1(byte *fn, byte *argp, int32 narg, int32 nret)
|
|||||||
newg->sched.pc = (byte*)runtime·goexit;
|
newg->sched.pc = (byte*)runtime·goexit;
|
||||||
newg->sched.g = newg;
|
newg->sched.g = newg;
|
||||||
newg->entry = fn;
|
newg->entry = fn;
|
||||||
|
newg->gopc = (uintptr)callerpc;
|
||||||
|
|
||||||
runtime·sched.gcount++;
|
runtime·sched.gcount++;
|
||||||
runtime·goidgen++;
|
runtime·goidgen++;
|
||||||
|
@ -202,6 +202,7 @@ struct G
|
|||||||
uintptr sigcode0;
|
uintptr sigcode0;
|
||||||
uintptr sigcode1;
|
uintptr sigcode1;
|
||||||
uintptr sigpc;
|
uintptr sigpc;
|
||||||
|
uintptr gopc; // pc of go statement that created this goroutine
|
||||||
};
|
};
|
||||||
struct M
|
struct M
|
||||||
{
|
{
|
||||||
@ -452,7 +453,7 @@ void runtime·entersyscall(void);
|
|||||||
void runtime·exitsyscall(void);
|
void runtime·exitsyscall(void);
|
||||||
void runtime·startcgocallback(G*);
|
void runtime·startcgocallback(G*);
|
||||||
void runtime·endcgocallback(G*);
|
void runtime·endcgocallback(G*);
|
||||||
G* runtime·newproc1(byte*, byte*, int32, int32);
|
G* runtime·newproc1(byte*, byte*, int32, int32, void*);
|
||||||
void runtime·siginit(void);
|
void runtime·siginit(void);
|
||||||
bool runtime·sigsend(int32 sig);
|
bool runtime·sigsend(int32 sig);
|
||||||
void runtime·gettime(int64*, int32*);
|
void runtime·gettime(int64*, int32*);
|
||||||
|
Loading…
Reference in New Issue
Block a user