mirror of
https://github.com/golang/go
synced 2024-11-26 22:01:27 -07:00
runtime: mark cgo callback results as written for msan
This is a fix for the -msan option when using cgo callbacks. A cgo callback works by writing out C code that puts a struct on the stack and passes the address of that struct into Go. The result parameters are fields of the struct. The Go code will write to the result parameters, but the Go code thinks it is just writing into the Go stack, and therefore won't call msanwrite. This CL adds a call to msanwrite in the cgo callback code so that the C knows that results were written. Change-Id: I80438dbd4561502bdee97fad3f02893a06880ee1 Reviewed-on: https://go-review.googlesource.com/16611 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
f84420c20d
commit
8f3f2ccac0
32
misc/cgo/testsanitizers/msan3.go
Normal file
32
misc/cgo/testsanitizers/msan3.go
Normal file
@ -0,0 +1,32 @@
|
||||
// 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
|
||||
|
||||
/*
|
||||
extern int *GoFn(void);
|
||||
|
||||
// Yes, you can have definitions if you use //export, as long as they are weak.
|
||||
int f(void) __attribute__ ((weak));
|
||||
|
||||
int f() {
|
||||
int *p = GoFn();
|
||||
if (*p != 12345)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
//export GoFn
|
||||
func GoFn() *C.int {
|
||||
i := C.int(12345)
|
||||
return &i
|
||||
}
|
||||
|
||||
func main() {
|
||||
if r := C.f(); r != 1 {
|
||||
panic(r)
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ export CC
|
||||
|
||||
TMPDIR=${TMPDIR:-/tmp}
|
||||
echo > ${TMPDIR}/testsanitizers$$.c
|
||||
if $CC -fsanitize=memory -c ${TMPDIR}/testsanitizers$$.c 2>&1 | grep "unrecognized" >& /dev/null; then
|
||||
if $CC -fsanitize=memory -c ${TMPDIR}/testsanitizers$$.c -o ${TMPDIR}/testsanitizers$$.o 2>&1 | grep "unrecognized" >& /dev/null; then
|
||||
echo "skipping msan test: -fsanitize=memory not supported"
|
||||
rm -f ${TMPDIR}/testsanitizers$$.*
|
||||
exit 0
|
||||
@ -52,6 +52,11 @@ if ! go run -msan msan2.go; then
|
||||
status=1
|
||||
fi
|
||||
|
||||
if ! go run -msan msan3.go; then
|
||||
echo "FAIL: msan3"
|
||||
status=1
|
||||
fi
|
||||
|
||||
if go run -msan msan_fail.go 2>/dev/null; then
|
||||
echo "FAIL: msan_fail"
|
||||
status=1
|
||||
|
@ -266,6 +266,13 @@ func cgocallbackg1() {
|
||||
if raceenabled {
|
||||
racereleasemerge(unsafe.Pointer(&racecgosync))
|
||||
}
|
||||
if msanenabled {
|
||||
// Tell msan that we wrote to the entire argument block.
|
||||
// This tells msan that we set the results.
|
||||
// Since we have already called the function it doesn't
|
||||
// matter that we are writing to the non-result parameters.
|
||||
msanwrite(cb.arg, cb.argsize)
|
||||
}
|
||||
|
||||
// Do not unwind m->g0->sched.sp.
|
||||
// Our caller, cgocallback, will do that.
|
||||
|
Loading…
Reference in New Issue
Block a user