From: Bryan C. Mills Date: Mon, 7 Aug 2017 23:30:03 +0000 (-0400) Subject: runtime/cgo: defeat inlining in x_cgo_yield X-Git-Tag: go1.10beta1~1510 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e0545faf270fdbc0b3864db62f528eb36da3c63f;p=gostls13.git runtime/cgo: defeat inlining in x_cgo_yield We use a call to strncpy to work around a TSAN bug (wherein TSAN only delivers asynchronous signals when the thread receiving the signal calls a libc function). Unfortunately, GCC 7 inlines the call, avoiding the TSAN libc trap entirely. Per Ian's suggestion, use global variables as strncpy arguments: that way, the compiler can't make any assumptions about the concrete values and can't inline the call away. fixes #21196 Change-Id: Ie95f1feaf9af1a8056f924f49c29cfc8515385d7 Reviewed-on: https://go-review.googlesource.com/55872 Reviewed-by: Ian Lance Taylor --- diff --git a/src/runtime/cgo/gcc_util.c b/src/runtime/cgo/gcc_util.c index 2d5382a8f0..3fcb48cc8d 100644 --- a/src/runtime/cgo/gcc_util.c +++ b/src/runtime/cgo/gcc_util.c @@ -29,6 +29,10 @@ void(* const _cgo_yield)() = NULL; #include +char x_cgo_yield_strncpy_src = 0; +char x_cgo_yield_strncpy_dst = 0; +size_t x_cgo_yield_strncpy_n = 0; + /* Stub for allowing libc interceptors to execute. @@ -50,9 +54,14 @@ x_cgo_yield() So we choose strncpy(_, _, 0): it requires an extra header, but it's standard and should be very efficient. + + GCC 7 has an unfortunate habit of optimizing out strncpy calls (see + https://golang.org/issue/21196), so the arguments here need to be global + variables with external linkage in order to ensure that the call traps all the + way down into libc. */ - char nothing = 0; - strncpy(¬hing, ¬hing, 0); + strncpy(&x_cgo_yield_strncpy_dst, &x_cgo_yield_strncpy_src, + x_cgo_yield_strncpy_n); } void(* const _cgo_yield)() = &x_cgo_yield;