runtime: don't fetch G from signal stack when using cgo

When using cgo, we save G to TLS, and when a signal happens, we
load G from TLS in sigtramp. This should give us a valid G. Don't
try to fetch from the signal stack. In particular, C code may
change the signal stack or call our signal handler directly (e.g.
TSAN), so we are not necessarily running on the original gsignal
stack where we saved G.

Also skip saving G on the signal stack when using cgo.

Updates #35249.

Change-Id: I40749ce6682709bd4ebfdfd9f23bd0f317fc197d
Reviewed-on: https://go-review.googlesource.com/c/go/+/204519
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Cherry Zhang 2019-10-31 10:32:31 -04:00
parent fb05264fe1
commit f07cbc7f88
3 changed files with 47 additions and 17 deletions

View file

@ -360,9 +360,11 @@ func preemptM(mp *m) {
func sigFetchG(c *sigctxt) *g {
switch GOARCH {
case "arm", "arm64":
if inVDSOPage(c.sigpc()) {
// Before making a VDSO call we save the g to the bottom of the
// signal stack. Fetch from there.
if !iscgo && inVDSOPage(c.sigpc()) {
// When using cgo, we save the g on TLS and load it from there
// in sigtramp. Just use that.
// Otherwise, before making a VDSO call we save the g to the
// bottom of the signal stack. Fetch from there.
// TODO: in efence mode, stack is sysAlloc'd, so this wouldn't
// work.
sp := getcallersp()