]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: don't call msanread when running on the system stack
authorIan Lance Taylor <iant@golang.org>
Wed, 4 Nov 2015 20:30:30 +0000 (12:30 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 11 Nov 2015 06:04:04 +0000 (06:04 +0000)
The runtime is not instrumented, but the calls to msanread in the
runtime can sometimes refer to the system stack.  An example is the call
to copy in stkbucket in mprof.go.  Depending on what C code has done,
the system stack may appear uninitialized to msan.

Change-Id: Ic21705b9ac504ae5cf7601a59189302f072e7db1
Reviewed-on: https://go-review.googlesource.com/16660
Reviewed-by: David Crawshaw <crawshaw@golang.org>
misc/cgo/testsanitizers/msan.go
misc/cgo/testsanitizers/msan2.go
misc/cgo/testsanitizers/msan4.go [new file with mode: 0644]
misc/cgo/testsanitizers/msan_fail.go
misc/cgo/testsanitizers/test.bash
src/runtime/msan.go
src/runtime/msan_amd64.s

index 263fb5a2f771d19d096084cb5e18cab83a13803b..ebfd5c3bd81ba7c9ff76b33ef036e832ab8fa9bd 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright 2015 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package main
 
 /*
index d1da89c912529f98169a80b2ceb012ac460d9d9e..42dcd20c088b019befa136a6a46d6a4c36f9c517 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright 2015 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package main
 
 /*
diff --git a/misc/cgo/testsanitizers/msan4.go b/misc/cgo/testsanitizers/msan4.go
new file mode 100644 (file)
index 0000000..c75e1c3
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2015 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// The memory profiler can call copy from a slice on the system stack,
+// which msan used to think meant a reference to uninitialized memory.
+
+/*
+#include <time.h>
+#include <unistd.h>
+
+extern void Nop(char*);
+
+// Use weak as a hack to permit defining a function even though we use export.
+void poison() __attribute__ ((weak));
+
+// Poison the stack.
+void poison() {
+       char a[1024];
+       Nop(&a[0]);
+}
+
+*/
+import "C"
+
+import (
+       "runtime"
+)
+
+func main() {
+       runtime.MemProfileRate = 1
+       start(100)
+}
+
+func start(i int) {
+       if i == 0 {
+               return
+       }
+       C.poison()
+       // Tie up a thread.
+       // We won't actually wait for this sleep to complete.
+       go func() { C.sleep(1) }()
+       start(i - 1)
+}
+
+//export Nop
+func Nop(*C.char) {
+}
index 50379a94d7ab5f229c92f222fa4b4a50ef3a2bb1..757e22c3da1f4325d39de677afa0808e647c4263 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright 2015 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package main
 
 /*
index a4cff2770156cef5aab1cba892c34bc22bb72011..0c28249c1b2b187373eb023e2a6955f275a6940d 100755 (executable)
@@ -57,6 +57,11 @@ if ! go run -msan msan3.go; then
   status=1
 fi
 
+if ! go run -msan msan4.go; then
+  echo "FAIL: msan4"
+  status=1
+fi
+
 if go run -msan msan_fail.go 2>/dev/null; then
   echo "FAIL: msan_fail"
   status=1
index 7457fe1150ce07be3b3691f30b0119f68c97edcc..4dbdf05b21c5cfcac83a6b17d876eb673c04f14f 100644 (file)
@@ -23,8 +23,21 @@ func MSanWrite(addr unsafe.Pointer, len int) {
 // Private interface for the runtime.
 const msanenabled = true
 
+// If we are running on the system stack, the C program may have
+// marked part of that stack as uninitialized.  We don't instrument
+// the runtime, but operations like a slice copy can call msanread
+// anyhow for values on the stack.  Just ignore msanread when running
+// on the system stack.  The other msan functions are fine.
+func msanread(addr unsafe.Pointer, sz uintptr) {
+       g := getg()
+       if g == g.m.g0 || g == g.m.gsignal {
+               return
+       }
+       domsanread(addr, sz)
+}
+
 //go:noescape
-func msanread(addr unsafe.Pointer, sz uintptr)
+func domsanread(addr unsafe.Pointer, sz uintptr)
 
 //go:noescape
 func msanwrite(addr unsafe.Pointer, sz uintptr)
index 6e8c1a10fc93c4b216af0cd415aba4b7d4961da8..613149593f684a5ac5ae829bf5d551f8034ec5c8 100644 (file)
@@ -24,9 +24,9 @@
 #define RARG3 CX
 #endif
 
-// func runtime·msanread(addr unsafe.Pointer, sz uintptr)
-// Called from instrumented code.
-TEXT   runtime·msanread(SB), NOSPLIT, $0-16
+// func runtime·domsanread(addr unsafe.Pointer, sz uintptr)
+// Called from msanread.
+TEXT   runtime·domsanread(SB), NOSPLIT, $0-16
        MOVQ    addr+0(FP), RARG0
        MOVQ    size+8(FP), RARG1
        // void __msan_read_go(void *addr, uintptr_t sz);