1
0
mirror of https://github.com/golang/go synced 2024-11-05 23:26:18 -07:00
go/misc/cgo/testsanitizers/tsan5.go
Ian Lance Taylor 66736880ca runtime/cgo: add TSAN acquire/release calls
Add TSAN acquire/release calls to runtime/cgo to match the ones
generated by cgo.  This avoids a false positive race around the malloc
memory used in runtime/cgo when other goroutines are simultaneously
calling malloc and free from cgo.

These new calls will only be used when building with CGO_CFLAGS and
CGO_LDFLAGS set to -fsanitize=thread, which becomes a requirement to
avoid all false positives when using TSAN.  These are needed not just
for runtime/cgo, but also for any runtime package that uses cgo (such as
net and os/user).

Add an unused attribute to the _cgo_tsan_acquire and _cgo_tsan_release
functions, in case there are no actual cgo function calls.

Add a test that checks that setting CGO_CFLAGS/CGO_LDFLAGS avoids a
false positive report when using os/user.

Change-Id: I0905c644ff7f003b6718aac782393fa219514c48
Reviewed-on: https://go-review.googlesource.com/23492
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
2016-05-31 20:53:16 +00:00

52 lines
927 B
Go

// Copyright 2016 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
// Check that calls to C.malloc/C.free do not collide with the calls
// made by the os/user package.
// #cgo CFLAGS: -fsanitize=thread
// #cgo LDFLAGS: -fsanitize=thread
// #include <stdlib.h>
import "C"
import (
"fmt"
"os"
"os/user"
"runtime"
"sync"
)
func main() {
u, err := user.Current()
if err != nil {
fmt.Fprintln(os.Stderr, err)
// Let the test pass.
os.Exit(0)
}
var wg sync.WaitGroup
for i := 0; i < 20; i++ {
wg.Add(2)
go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
user.Lookup(u.Username)
runtime.Gosched()
}
}()
go func() {
defer wg.Done()
for i := 0; i < 1000; i++ {
p := C.malloc(C.size_t(len(u.Username) + 1))
runtime.Gosched()
C.free(p)
}
}()
}
wg.Wait()
}