]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo, runtime/cgo: add docs for TSAN interaction
authorIan Lance Taylor <iant@golang.org>
Thu, 25 May 2017 19:20:58 +0000 (12:20 -0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 26 May 2017 05:22:39 +0000 (05:22 +0000)
Change-Id: I3b3ae4ecad0894781a3019326c7262cb9790ad4d
Reviewed-on: https://go-review.googlesource.com/44250
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
src/cmd/cgo/out.go
src/runtime/cgo/libcgo.h

index 274bb1fb1af9f457a085d5fe55b84cc38f8dbd84..9ab6bd8f977b33e27f4abdea7f0fb262f406a6d6 100644 (file)
@@ -1323,6 +1323,27 @@ const noTsanProlog = `
 `
 
 // This must match the TSAN code in runtime/cgo/libcgo.h.
+// This is used when the code is built with the C/C++ Thread SANitizer,
+// which is not the same as the Go race detector.
+// __tsan_acquire tells TSAN that we are acquiring a lock on a variable,
+// in this case _cgo_sync. __tsan_release releases the lock.
+// (There is no actual lock, we are just telling TSAN that there is.)
+//
+// When we call from Go to C we call _cgo_tsan_acquire.
+// When the C function returns we call _cgo_tsan_release.
+// Similarly, when C calls back into Go we call _cgo_tsan_release
+// and then call _cgo_tsan_acquire when we return to C.
+// These calls tell TSAN that there is a serialization point at the C call.
+//
+// This is necessary because TSAN, which is a C/C++ tool, can not see
+// the synchronization in the Go code. Without these calls, when
+// multiple goroutines call into C code, TSAN does not understand
+// that the calls are properly synchronized on the Go side.
+//
+// To be clear, if the calls are not properly synchronized on the Go side,
+// we will be hiding races. But when using TSAN on mixed Go C/C++ code
+// it is more important to avoid false positives, which reduce confidence
+// in the tool, than to avoid false negatives.
 const yesTsanProlog = `
 #line 1 "cgo-tsan-prolog"
 #define CGO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize_thread))
index 01f9e721745300c198858a7700f59e619183cda7..2b8b4e25a29a94e393aa4201b5c4dc608378d812 100644 (file)
@@ -111,6 +111,11 @@ extern void (*(_cgo_get_context_function(void)))(struct context_arg*);
 #ifdef CGO_TSAN
 
 // These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
+// In general we should call _cgo_tsan_acquire when we enter C code,
+// and call _cgo_tsan_release when we return to Go code.
+// This is only necessary when calling code that might be instrumented
+// by TSAN, which mostly means system library calls that TSAN intercepts.
+// See the comment in cmd/cgo/out.go for more details.
 
 long long _cgo_sync __attribute__ ((common));