mirror of https://github.com/golang/go.git
runtime: don't call msanread when running on the system stack
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>
This commit is contained in:
parent
8f3f2ccac0
commit
880a689124
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue