1
0
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:
Dmitriy Vyukov 2013-08-01 19:28:38 +04:00
parent 3cbc2716a9
commit c33d490020
4 changed files with 19 additions and 15 deletions

View File

@ -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);
} }
} }

View File

@ -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*);

View File

@ -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)

View File

@ -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