Skip to content

Commit 7529314

Browse files
aclementsrsc
authored andcommitted
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 <[email protected]>
1 parent 24de40a commit 7529314

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

src/runtime/mgcmark.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,17 @@ func scanstack(gp *g) {
315315
throw("can't scan gchelper stack")
316316
}
317317

318-
var barrierOffset, nextBarrier uintptr
318+
var sp, barrierOffset, nextBarrier uintptr
319+
if gp.syscallsp != 0 {
320+
sp = gp.syscallsp
321+
} else {
322+
sp = gp.sched.sp
323+
}
319324
switch gcphase {
320325
case _GCscan:
321326
// Install stack barriers during stack scan.
322327
barrierOffset = firstStackBarrierOffset
323-
nextBarrier = gp.sched.sp + barrierOffset
328+
nextBarrier = sp + barrierOffset
324329

325330
if gp.stkbarPos != 0 || len(gp.stkbar) != 0 {
326331
// If this happens, it's probably because we
@@ -342,7 +347,7 @@ func scanstack(gp *g) {
342347
// this barrier had write barriers.
343348
nextBarrier = gp.stkbar[gp.stkbarPos].savedLRPtr
344349
if debugStackBarrier {
345-
print("rescan below ", hex(nextBarrier), " in [", hex(gp.sched.sp), ",", hex(gp.stack.hi), ") goid=", gp.goid, "\n")
350+
print("rescan below ", hex(nextBarrier), " in [", hex(sp), ",", hex(gp.stack.hi), ") goid=", gp.goid, "\n")
346351
}
347352
}
348353

@@ -364,7 +369,7 @@ func scanstack(gp *g) {
364369
if gcphase == _GCscan && n != 0 {
365370
gcInstallStackBarrier(gp, frame)
366371
barrierOffset *= 2
367-
nextBarrier = gp.sched.sp + barrierOffset
372+
nextBarrier = sp + barrierOffset
368373
} else if gcphase == _GCmarktermination {
369374
// We just scanned a frame containing
370375
// a return to a stack barrier. Since

0 commit comments

Comments
 (0)