Commit 880a6891 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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/16660Reviewed-by: 's avatarDavid Crawshaw <crawshaw@golang.org>
parent 8f3f2cca
// 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
/*
......
// 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
/*
......
// 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) {
}
// 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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment