mirror of
https://github.com/golang/go
synced 2024-11-18 06:04:53 -07:00
cmd/cgo, runtime/cgo: add docs for TSAN interaction
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>
This commit is contained in:
parent
ffab6ab877
commit
6654e3e0a1
@ -1323,6 +1323,27 @@ const noTsanProlog = `
|
|||||||
`
|
`
|
||||||
|
|
||||||
// This must match the TSAN code in runtime/cgo/libcgo.h.
|
// 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 = `
|
const yesTsanProlog = `
|
||||||
#line 1 "cgo-tsan-prolog"
|
#line 1 "cgo-tsan-prolog"
|
||||||
#define CGO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize_thread))
|
#define CGO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize_thread))
|
||||||
|
@ -111,6 +111,11 @@ extern void (*(_cgo_get_context_function(void)))(struct context_arg*);
|
|||||||
#ifdef CGO_TSAN
|
#ifdef CGO_TSAN
|
||||||
|
|
||||||
// These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
|
// 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));
|
long long _cgo_sync __attribute__ ((common));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user