]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use correct SP when installing stack barriers
authorAustin Clements <austin@google.com>
Fri, 5 Jun 2015 15:07:21 +0000 (11:07 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 5 Jun 2015 15:53:07 +0000 (15:53 +0000)
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>
src/runtime/mgcmark.go

index f491e51a058e4253384e24bd1ac63f9306252199..ecb6d93a4f8a834aae1ea92870f8121ef41cb5ce 100644 (file)
@@ -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