mirror of
https://github.com/golang/go
synced 2024-11-19 13:04:45 -07:00
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 <iant@golang.org>
This commit is contained in:
parent
58f84fdf29
commit
e0545faf27
@ -29,6 +29,10 @@ void(* const _cgo_yield)() = NULL;
|
||||
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user