aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-02-28 17:13:59 -0500
committerRuss Cox <rsc@golang.org>2014-02-28 17:13:59 -0500
commit1685fbd1845ec9778158a82dcaf96cf154c5376d (patch)
tree48e91adefe0a1bc9fda2cc83aad50d631197016b
parent0d2f5c0e3b4cddd4bd8349169e0c29e0862b44e3 (diff)
downloadgo-1685fbd1845ec9778158a82dcaf96cf154c5376d.tar.gz
go-1685fbd1845ec9778158a82dcaf96cf154c5376d.zip
[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 #6946. R=iant, r CC=golang-dev https://golang.org/cl/41640043 »»» LGTM=adg R=adg CC=golang-codereviews, golang-dev, iant, r https://golang.org/cl/68820045
-rw-r--r--src/pkg/runtime/mprof.goc4
-rw-r--r--src/pkg/runtime/proc.c4
-rw-r--r--src/pkg/runtime/traceback_arm.c12
-rw-r--r--src/pkg/runtime/traceback_x86.c10
4 files changed, 26 insertions, 4 deletions
diff --git a/src/pkg/runtime/mprof.goc b/src/pkg/runtime/mprof.goc
index 5b92cec95c..4ae74f0c28 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 de26c72d3d..ed3e1e73ee 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 341aa20588..8a3685e76c 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 d658e8f11a..8e3063f43a 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);