Commit e0545faf authored by Bryan C. Mills's avatar Bryan C. Mills Committed by Bryan Mills

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/55872Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 58f84fdf
......@@ -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(&nothing, &nothing, 0);
strncpy(&x_cgo_yield_strncpy_dst, &x_cgo_yield_strncpy_src,
x_cgo_yield_strncpy_n);
}
void(* const _cgo_yield)() = &x_cgo_yield;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment