aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mgcmark.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2016-05-27 12:21:14 -0400
committerAustin Clements <austin@google.com>2016-05-27 17:53:21 +0000
commit6a86dbe75f6d5a135eefbae807d98e856136514f (patch)
treeb79ece30bdb26c6be61462cb1dc73a948373efd1 /src/runtime/mgcmark.go
parent966baedfea6b09fa203b0cf0e6388830cc9f9fa7 (diff)
downloadgo-6a86dbe75f6d5a135eefbae807d98e856136514f.tar.xz
runtime: always call stackfree on the system stack
Currently when the garbage collector frees stacks of dead goroutines in markrootFreeGStacks, it calls stackfree on a regular user stack. This is a problem, since stackfree manipulates the stack cache in the per-P mcache, so if it grows the stack or gets preempted in the middle of manipulating the stack cache (which are both possible since it's on a user stack), it can easily corrupt the stack cache. Fix this by calling markrootFreeGStacks on the system stack, so that all calls to stackfree happen on the system stack. To prevent this bug in the future, mark stack functions that manipulate the mcache as go:systemstack. Fixes #15853. Change-Id: Ic0d1c181efb342f134285a152560c3a074f14a3d Reviewed-on: https://go-review.googlesource.com/23511 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/runtime/mgcmark.go')
-rw-r--r--src/runtime/mgcmark.go4
1 files changed, 3 insertions, 1 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 2d0cbd203c..00b96fd00b 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -174,7 +174,9 @@ func markroot(gcw *gcWork, i uint32) {
// Only do this once per GC cycle; preferably
// concurrently.
if !work.markrootDone {
- markrootFreeGStacks()
+ // Switch to the system stack so we can call
+ // stackfree.
+ systemstack(markrootFreeGStacks)
}
case baseSpans <= i && i < baseStacks: