Commit 7529314e authored by Austin Clements's avatar Austin Clements Committed by Russ Cox

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/10755Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 24de40a8
...@@ -315,12 +315,17 @@ func scanstack(gp *g) { ...@@ -315,12 +315,17 @@ func scanstack(gp *g) {
throw("can't scan gchelper stack") 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 { switch gcphase {
case _GCscan: case _GCscan:
// Install stack barriers during stack scan. // Install stack barriers during stack scan.
barrierOffset = firstStackBarrierOffset barrierOffset = firstStackBarrierOffset
nextBarrier = gp.sched.sp + barrierOffset nextBarrier = sp + barrierOffset
if gp.stkbarPos != 0 || len(gp.stkbar) != 0 { if gp.stkbarPos != 0 || len(gp.stkbar) != 0 {
// If this happens, it's probably because we // If this happens, it's probably because we
...@@ -342,7 +347,7 @@ func scanstack(gp *g) { ...@@ -342,7 +347,7 @@ func scanstack(gp *g) {
// this barrier had write barriers. // this barrier had write barriers.
nextBarrier = gp.stkbar[gp.stkbarPos].savedLRPtr nextBarrier = gp.stkbar[gp.stkbarPos].savedLRPtr
if debugStackBarrier { 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) { ...@@ -364,7 +369,7 @@ func scanstack(gp *g) {
if gcphase == _GCscan && n != 0 { if gcphase == _GCscan && n != 0 {
gcInstallStackBarrier(gp, frame) gcInstallStackBarrier(gp, frame)
barrierOffset *= 2 barrierOffset *= 2
nextBarrier = gp.sched.sp + barrierOffset nextBarrier = sp + barrierOffset
} else if gcphase == _GCmarktermination { } else if gcphase == _GCmarktermination {
// We just scanned a frame containing // We just scanned a frame containing
// a return to a stack barrier. Since // a return to a stack barrier. Since
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment