aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-06-05 11:07:21 -0400
committerRuss Cox <rsc@golang.org>2015-06-05 15:53:07 +0000
commit7529314ed37fdb94af2a25405edcb26ccb243b8e (patch)
tree058e8c9105a76693183c44c69aa1f2ed4ae0c5bb /src/runtime
parent24de40a8461a48f814c1bd37a1a6b911c922366f (diff)
downloadgo-7529314ed37fdb94af2a25405edcb26ccb243b8e.tar.xz
runtime: use correct SP when installing stack barriers
Currently the stack barriers are installed at the next frame boundary after gp.sched.sp + 1024*2^n for n=0,1,2,... However, when a G is in a system call, we set gp.sched.sp to 0, which causes stack barriers to be installed at *every* frame. This easily overflows the slice we've reserved for storing the stack barrier information, and causes a "slice bounds out of range" panic in gcInstallStackBarrier. Fix this by using gp.syscallsp instead of gp.sched.sp if it's non-zero. This is the same logic that gentraceback uses to determine the current SP. Fixes #11049. Change-Id: Ie40eeee5bec59b7c1aa715a7c17aa63b1f1cf4e8 Reviewed-on: https://go-review.googlesource.com/10755 Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/mgcmark.go13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index f491e51a05..ecb6d93a4f 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -315,12 +315,17 @@ func scanstack(gp *g) {
throw("can't scan gchelper stack")
}
- var barrierOffset, nextBarrier uintptr
+ var sp, barrierOffset, nextBarrier uintptr
+ if gp.syscallsp != 0 {
+ sp = gp.syscallsp
+ } else {
+ sp = gp.sched.sp
+ }
switch gcphase {
case _GCscan:
// Install stack barriers during stack scan.
barrierOffset = firstStackBarrierOffset
- nextBarrier = gp.sched.sp + barrierOffset
+ nextBarrier = sp + barrierOffset
if gp.stkbarPos != 0 || len(gp.stkbar) != 0 {
// If this happens, it's probably because we
@@ -342,7 +347,7 @@ func scanstack(gp *g) {
// this barrier had write barriers.
nextBarrier = gp.stkbar[gp.stkbarPos].savedLRPtr
if debugStackBarrier {
- print("rescan below ", hex(nextBarrier), " in [", hex(gp.sched.sp), ",", hex(gp.stack.hi), ") goid=", gp.goid, "\n")
+ print("rescan below ", hex(nextBarrier), " in [", hex(sp), ",", hex(gp.stack.hi), ") goid=", gp.goid, "\n")
}
}
@@ -364,7 +369,7 @@ func scanstack(gp *g) {
if gcphase == _GCscan && n != 0 {
gcInstallStackBarrier(gp, frame)
barrierOffset *= 2
- nextBarrier = gp.sched.sp + barrierOffset
+ nextBarrier = sp + barrierOffset
} else if gcphase == _GCmarktermination {
// We just scanned a frame containing
// a return to a stack barrier. Since