]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.5] runtime: take stack barrier lock during copystack
authorAustin Clements <austin@google.com>
Mon, 23 Nov 2015 20:03:38 +0000 (15:03 -0500)
committerAustin Clements <austin@google.com>
Tue, 24 Nov 2015 02:18:46 +0000 (02:18 +0000)
Commit bbd1a1c prevented SIGPROF from scanning stacks that were being
copied, but it didn't prevent a stack copy (specifically a stack
shrink) from happening while SIGPROF is scanning the stack. As a
result, a stack copy may adjust stack barriers while SIGPROF is in the
middle of scanning a stack, causing SIGPROF to panic when it detects
an inconsistent stack barrier.

Fix this by taking the stack barrier lock while adjusting the stack.
In addition to preventing SIGPROF from scanning this stack, this will
block until any in-progress SIGPROF is done scanning the stack.

For 1.5.2.

Fixes #13362.
Updates #12932.

Change-Id: I422219c363054410dfa56381f7b917e04690e5dd
Reviewed-on: https://go-review.googlesource.com/17191
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/17194

src/runtime/stack1.go

index efcb5f25fada67a8a95445fe477c30e36fbfabcd..19634ef6d58a12d57b683c2615e6460ec92b748e 100644 (file)
@@ -609,6 +609,10 @@ func copystack(gp *g, newsize uintptr) {
                print("copystack gp=", gp, " [", hex(old.lo), " ", hex(old.hi-used), " ", hex(old.hi), "]/", gp.stackAlloc, " -> [", hex(new.lo), " ", hex(new.hi-used), " ", hex(new.hi), "]/", newsize, "\n")
        }
 
+       // Disallow sigprof scans of this stack and block if there's
+       // one in progress.
+       gcLockStackBarriers(gp)
+
        // adjust pointers in the to-be-copied frames
        var adjinfo adjustinfo
        adjinfo.old = old
@@ -640,6 +644,8 @@ func copystack(gp *g, newsize uintptr) {
        gp.stackAlloc = newsize
        gp.stkbar = newstkbar
 
+       gcUnlockStackBarriers(gp)
+
        // free old stack
        if stackPoisonCopy != 0 {
                fillstack(old, 0xfc)