mirror of
https://github.com/golang/go
synced 2024-11-22 07:14:40 -07:00
runtime: print "created by" for running goroutines in traceback
This allows to at least determine goroutine "identity". Now it looks like: goroutine 12 [running]: goroutine running on other thread; stack unavailable created by testing.RunTests src/pkg/testing/testing.go:440 +0x88e R=golang-dev, r, rsc CC=golang-dev https://golang.org/cl/12248043
This commit is contained in:
parent
3cbc2716a9
commit
c33d490020
@ -267,9 +267,10 @@ runtime·tracebackothers(G *me)
|
|||||||
continue;
|
continue;
|
||||||
runtime·printf("\n");
|
runtime·printf("\n");
|
||||||
runtime·goroutineheader(gp);
|
runtime·goroutineheader(gp);
|
||||||
if(gp->status == Grunning)
|
if(gp->status == Grunning) {
|
||||||
runtime·printf("\tgoroutine running on other thread; stack unavailable\n");
|
runtime·printf("\tgoroutine running on other thread; stack unavailable\n");
|
||||||
else
|
runtime·printcreatedby(gp);
|
||||||
|
} else
|
||||||
runtime·traceback(gp->sched.pc, gp->sched.sp, gp->sched.lr, gp);
|
runtime·traceback(gp->sched.pc, gp->sched.sp, gp->sched.lr, gp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1039,6 +1039,7 @@ Hchan* runtime·makechan_c(ChanType*, int64);
|
|||||||
void runtime·chansend(ChanType*, Hchan*, byte*, bool*, void*);
|
void runtime·chansend(ChanType*, Hchan*, byte*, bool*, void*);
|
||||||
void runtime·chanrecv(ChanType*, Hchan*, byte*, bool*, bool*);
|
void runtime·chanrecv(ChanType*, Hchan*, byte*, bool*, bool*);
|
||||||
bool runtime·showframe(Func*, G*);
|
bool runtime·showframe(Func*, G*);
|
||||||
|
void runtime·printcreatedby(G*);
|
||||||
|
|
||||||
void runtime·ifaceE2I(InterfaceType*, Eface, Iface*);
|
void runtime·ifaceE2I(InterfaceType*, Eface, Iface*);
|
||||||
|
|
||||||
|
@ -193,20 +193,21 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
printcreatedby(G *gp)
|
runtime·printcreatedby(G *gp)
|
||||||
{
|
{
|
||||||
int32 line;
|
int32 line;
|
||||||
uintptr pc, tracepc;
|
uintptr pc, tracepc;
|
||||||
Func *f;
|
Func *f;
|
||||||
String file;
|
String file;
|
||||||
|
|
||||||
if((pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil
|
// Show what created goroutine, except main goroutine (goid 1).
|
||||||
&& runtime·showframe(f, gp) && gp->goid != 1) {
|
if((pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil &&
|
||||||
|
runtime·showframe(f, gp) && gp->goid != 1) {
|
||||||
runtime·printf("created by %s\n", runtime·funcname(f));
|
runtime·printf("created by %s\n", runtime·funcname(f));
|
||||||
tracepc = pc; // back up to CALL instruction for funcline.
|
tracepc = pc; // back up to CALL instruction for funcline.
|
||||||
if(pc > f->entry)
|
if(pc > f->entry)
|
||||||
tracepc -= sizeof(uintptr);
|
tracepc -= PCQuantum;
|
||||||
line = runtime·funcline(f, tracepc, &file);
|
line = runtime·funcline(f, tracepc, &file);
|
||||||
runtime·printf("\t%S:%d", file, line);
|
runtime·printf("\t%S:%d", file, line);
|
||||||
if(pc > f->entry)
|
if(pc > f->entry)
|
||||||
@ -229,7 +230,7 @@ runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G *gp)
|
|||||||
// If that means we print nothing at all, repeat forcing all frames printed.
|
// If that means we print nothing at all, repeat forcing all frames printed.
|
||||||
if(runtime·gentraceback(pc, sp, lr, gp, 0, nil, 100, nil, nil, false) == 0)
|
if(runtime·gentraceback(pc, sp, lr, gp, 0, nil, 100, nil, nil, false) == 0)
|
||||||
runtime·gentraceback(pc, sp, lr, gp, 0, nil, 100, nil, nil, true);
|
runtime·gentraceback(pc, sp, lr, gp, 0, nil, 100, nil, nil, true);
|
||||||
printcreatedby(gp);
|
runtime·printcreatedby(gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// func caller(n int) (pc uintptr, file string, line int, ok bool)
|
// func caller(n int) (pc uintptr, file string, line int, ok bool)
|
||||||
|
@ -199,21 +199,22 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
printcreatedby(G *gp)
|
runtime·printcreatedby(G *gp)
|
||||||
{
|
{
|
||||||
int32 line;
|
int32 line;
|
||||||
String file;
|
|
||||||
uintptr pc, tracepc;
|
uintptr pc, tracepc;
|
||||||
Func *f;
|
Func *f;
|
||||||
|
String file;
|
||||||
|
|
||||||
// Show what created goroutine, except main goroutine (goid 1).
|
// Show what created goroutine, except main goroutine (goid 1).
|
||||||
if((pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil && gp->goid != 1) {
|
if((pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil &&
|
||||||
|
runtime·showframe(f, gp) && gp->goid != 1) {
|
||||||
runtime·printf("created by %s\n", runtime·funcname(f));
|
runtime·printf("created by %s\n", runtime·funcname(f));
|
||||||
tracepc = pc; // back up to CALL instruction for funcline.
|
tracepc = pc; // back up to CALL instruction for funcline.
|
||||||
if(pc > f->entry)
|
if(pc > f->entry)
|
||||||
tracepc--;
|
tracepc -= PCQuantum;
|
||||||
line = runtime·funcline(f, tracepc, &file);
|
line = runtime·funcline(f, tracepc, &file);
|
||||||
runtime·printf("\t%S:%d", file, line);
|
runtime·printf("\t%S:%d", file, line);
|
||||||
if(pc > f->entry)
|
if(pc > f->entry)
|
||||||
runtime·printf(" +%p", (uintptr)(pc - f->entry));
|
runtime·printf(" +%p", (uintptr)(pc - f->entry));
|
||||||
@ -236,7 +237,7 @@ runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G *gp)
|
|||||||
// If that means we print nothing at all, repeat forcing all frames printed.
|
// If that means we print nothing at all, repeat forcing all frames printed.
|
||||||
if(runtime·gentraceback(pc, sp, 0, gp, 0, nil, 100, nil, nil, false) == 0)
|
if(runtime·gentraceback(pc, sp, 0, gp, 0, nil, 100, nil, nil, false) == 0)
|
||||||
runtime·gentraceback(pc, sp, 0, gp, 0, nil, 100, nil, nil, true);
|
runtime·gentraceback(pc, sp, 0, gp, 0, nil, 100, nil, nil, true);
|
||||||
printcreatedby(gp);
|
runtime·printcreatedby(gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
|
Loading…
Reference in New Issue
Block a user