aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2017-08-04 10:36:40 -0700
committerIan Lance Taylor <iant@golang.org>2017-08-05 18:05:41 +0000
commitf096b5b340f6e831cf80cd39cbf88d4656d232fa (patch)
tree1814c48b303450276e9b843f5f29e6a880b0c20e
parent3e3da5463302ff6f73a78e60fa7027d554095520 (diff)
downloadgo-f096b5b340f6e831cf80cd39cbf88d4656d232fa.tar.gz
go-f096b5b340f6e831cf80cd39cbf88d4656d232fa.zip
runtime: mark activeModules nosplit/nowritebarrier
The activeModules function is called by the cgo pointer checking code, which is called by the write barrier (when GODEBUG=cgocheck=2), and as such must be nosplit/nowritebarrier. Fixes #21306 Change-Id: I57f2124f14de7f3872b2de9532abab15df95d45a Reviewed-on: https://go-review.googlesource.com/53352 Reviewed-by: Austin Clements <austin@google.com>
-rw-r--r--misc/cgo/errors/ptr.go8
-rw-r--r--src/runtime/symtab.go5
2 files changed, 13 insertions, 0 deletions
diff --git a/misc/cgo/errors/ptr.go b/misc/cgo/errors/ptr.go
index 4dafbdf3c0..3e117666bf 100644
--- a/misc/cgo/errors/ptr.go
+++ b/misc/cgo/errors/ptr.go
@@ -343,6 +343,14 @@ var ptrTests = []ptrTest{
body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
fail: false,
},
+ {
+ // Issue #21306.
+ name: "preempt-during-call",
+ c: `void f() {}`,
+ imports: []string{"runtime", "sync"},
+ body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
+ fail: false,
+ },
}
func main() {
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 8e410c4560..e1b41ca4ff 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -409,6 +409,11 @@ var modulesSlice unsafe.Pointer // see activeModules
//
// A module is active once its gcdatamask and gcbssmask have been
// assembled and it is usable by the GC.
+//
+// This is nosplit/nowritebarrier because it is called by the
+// cgo pointer checking code.
+//go:nosplit
+//go:nowritebarrier
func activeModules() []*moduledata {
p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
if p == nil {