diff options
author | Russ Cox <rsc@golang.org> | 2014-02-28 17:13:59 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-02-28 17:13:59 -0500 |
commit | 9786b64364246375276a6f1ed85e9f77dcead4a2 (patch) | |
tree | 282deda15038a8b0598bd7645f086cd70c530398 | |
parent | 6dc75d34f149ee58c1c77fc1d45d7a9ff3d1ddd4 (diff) | |
download | go-9786b64364246375276a6f1ed85e9f77dcead4a2.tar.gz |
[release-branch.go1.2] runtime: fix crash in runtime.GoroutineProfile
This CL is not exactly a copy of the original quoted below.
This CL omits the changes made to mgc0.c in the original.
Those changes do not apply cleanly to the Go 1.2 tree,
and they were cosmetic, simplifying code that was already
doing the right thing.
To double-check that omitting the mgc0.c change has not
invalidated the fix, I have verified by hand that the test program
in issue 6946 fails without this CL and passes with this CL.
??? CL 41640043 / e4c381446b48
runtime: fix crash in runtime.GoroutineProfile
This is a possible Go 1.2.1 candidate.
Fixes issue 6946.
R=iant, r
CC=golang-dev
https://codereview.appspot.com/41640043
???
LGTM=adg
R=adg
CC=golang-codereviews, golang-dev, iant, r
https://codereview.appspot.com/68820045
-rw-r--r-- | src/pkg/runtime/mprof.goc | 4 | ||||
-rw-r--r-- | src/pkg/runtime/proc.c | 4 | ||||
-rw-r--r-- | src/pkg/runtime/traceback_arm.c | 12 | ||||
-rw-r--r-- | src/pkg/runtime/traceback_x86.c | 10 |
4 files changed, 26 insertions, 4 deletions
diff --git a/src/pkg/runtime/mprof.goc b/src/pkg/runtime/mprof.goc index 5b92cec95..4ae74f0c2 100644 --- a/src/pkg/runtime/mprof.goc +++ b/src/pkg/runtime/mprof.goc @@ -477,7 +477,7 @@ saveg(uintptr pc, uintptr sp, G *gp, TRecord *r) { int32 n; - n = runtime·gentraceback((uintptr)pc, (uintptr)sp, 0, gp, 0, r->stk, nelem(r->stk), nil, nil, false); + n = runtime·gentraceback(pc, sp, 0, gp, 0, r->stk, nelem(r->stk), nil, nil, false); if(n < nelem(r->stk)) r->stk[n] = 0; } @@ -505,7 +505,7 @@ func GoroutineProfile(b Slice) (n int, ok bool) { for(gp = runtime·allg; gp != nil; gp = gp->alllink) { if(gp == g || gp->status == Gdead) continue; - saveg(gp->sched.pc, gp->sched.sp, gp, r++); + saveg(~(uintptr)0, ~(uintptr)0, gp, r++); } } diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index de26c72d3..ed3e1e73e 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -276,7 +276,7 @@ runtime·tracebackothers(G *me) if((gp = m->curg) != nil && gp != me) { runtime·printf("\n"); runtime·goroutineheader(gp); - runtime·traceback(gp->sched.pc, gp->sched.sp, gp->sched.lr, gp); + runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, gp); } for(gp = runtime·allg; gp != nil; gp = gp->alllink) { @@ -290,7 +290,7 @@ runtime·tracebackothers(G *me) runtime·printf("\tgoroutine running on other thread; stack unavailable\n"); runtime·printcreatedby(gp); } else - runtime·traceback(gp->sched.pc, gp->sched.sp, gp->sched.lr, gp); + runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, gp); } } diff --git a/src/pkg/runtime/traceback_arm.c b/src/pkg/runtime/traceback_arm.c index 341aa2058..8a3685e76 100644 --- a/src/pkg/runtime/traceback_arm.c +++ b/src/pkg/runtime/traceback_arm.c @@ -20,6 +20,18 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, Stktop *stk; String file; + if(pc0 == ~(uintptr)0 && sp0 == ~(uintptr)0) { // Signal to fetch saved values from gp. + if(gp->syscallstack != (uintptr)nil) { + pc0 = gp->syscallpc; + sp0 = gp->syscallsp; + lr0 = 0; + } else { + pc0 = gp->sched.pc; + sp0 = gp->sched.sp; + lr0 = gp->sched.lr; + } + } + nprint = 0; runtime·memclr((byte*)&frame, sizeof frame); frame.pc = pc0; diff --git a/src/pkg/runtime/traceback_x86.c b/src/pkg/runtime/traceback_x86.c index d658e8f11..8e3063f43 100644 --- a/src/pkg/runtime/traceback_x86.c +++ b/src/pkg/runtime/traceback_x86.c @@ -30,6 +30,16 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, String file; USED(lr0); + + if(pc0 == ~(uintptr)0 && sp0 == ~(uintptr)0) { // Signal to fetch saved values from gp. + if(gp->syscallstack != (uintptr)nil) { + pc0 = gp->syscallpc; + sp0 = gp->syscallsp; + } else { + pc0 = gp->sched.pc; + sp0 = gp->sched.sp; + } + } nprint = 0; runtime·memclr((byte*)&frame, sizeof frame); |