Commit f07cbc7f authored by Cherry Zhang's avatar Cherry Zhang

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/+/204519Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent fb05264f
...@@ -360,9 +360,11 @@ func preemptM(mp *m) { ...@@ -360,9 +360,11 @@ func preemptM(mp *m) {
func sigFetchG(c *sigctxt) *g { func sigFetchG(c *sigctxt) *g {
switch GOARCH { switch GOARCH {
case "arm", "arm64": case "arm", "arm64":
if inVDSOPage(c.sigpc()) { if !iscgo && inVDSOPage(c.sigpc()) {
// Before making a VDSO call we save the g to the bottom of the // When using cgo, we save the g on TLS and load it from there
// signal stack. Fetch 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 // TODO: in efence mode, stack is sysAlloc'd, so this wouldn't
// work. // work.
sp := getcallersp() sp := getcallersp()
......
...@@ -277,21 +277,28 @@ noswitch: ...@@ -277,21 +277,28 @@ noswitch:
// during VDSO code we can find the g. // during VDSO code we can find the g.
// If we don't have a signal stack, we won't receive signal, // If we don't have a signal stack, we won't receive signal,
// so don't bother saving g. // so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
MOVB runtime·iscgo(SB), R6
CMP $0, R6
BNE nosaveg
MOVW m_gsignal(R5), R6 // g.m.gsignal MOVW m_gsignal(R5), R6 // g.m.gsignal
CMP $0, R6 CMP $0, R6
BEQ 3(PC) BEQ nosaveg
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
MOVW g, (R6) MOVW g, (R6)
BL (R11) BL (R11)
CMP $0, R6 // R6 is unchanged by C code
BEQ 3(PC)
MOVW $0, R1 MOVW $0, R1
MOVW R1, (R6) // clear g slot MOVW R1, (R6) // clear g slot, R6 is unchanged by C code
JMP finish JMP finish
nosaveg:
BL (R11)
JMP finish
fallback: fallback:
MOVW $SYS_clock_gettime, R7 MOVW $SYS_clock_gettime, R7
SWI $0 SWI $0
...@@ -344,21 +351,28 @@ noswitch: ...@@ -344,21 +351,28 @@ noswitch:
// during VDSO code we can find the g. // during VDSO code we can find the g.
// If we don't have a signal stack, we won't receive signal, // If we don't have a signal stack, we won't receive signal,
// so don't bother saving g. // so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
MOVB runtime·iscgo(SB), R6
CMP $0, R6
BNE nosaveg
MOVW m_gsignal(R5), R6 // g.m.gsignal MOVW m_gsignal(R5), R6 // g.m.gsignal
CMP $0, R6 CMP $0, R6
BEQ 3(PC) BEQ nosaveg
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
MOVW g, (R6) MOVW g, (R6)
BL (R11) BL (R11)
CMP $0, R6 // R6 is unchanged by C code
BEQ 3(PC)
MOVW $0, R1 MOVW $0, R1
MOVW R1, (R6) // clear g slot MOVW R1, (R6) // clear g slot, R6 is unchanged by C code
JMP finish JMP finish
nosaveg:
BL (R11)
JMP finish
fallback: fallback:
MOVW $SYS_clock_gettime, R7 MOVW $SYS_clock_gettime, R7
SWI $0 SWI $0
......
...@@ -237,18 +237,25 @@ noswitch: ...@@ -237,18 +237,25 @@ noswitch:
// during VDSO code we can find the g. // during VDSO code we can find the g.
// If we don't have a signal stack, we won't receive signal, // If we don't have a signal stack, we won't receive signal,
// so don't bother saving g. // so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
MOVBU runtime·iscgo(SB), R22
CBNZ R22, nosaveg
MOVD m_gsignal(R21), R22 // g.m.gsignal MOVD m_gsignal(R21), R22 // g.m.gsignal
CBZ R22, 3(PC) CBZ R22, nosaveg
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
MOVD g, (R22) MOVD g, (R22)
BL (R2) BL (R2)
CBZ R22, 2(PC) // R22 is unchanged by C code MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
MOVD ZR, (R22) // clear g slot
B finish B finish
nosaveg:
BL (R2)
B finish
fallback: fallback:
MOVD $SYS_clock_gettime, R8 MOVD $SYS_clock_gettime, R8
SVC SVC
...@@ -294,18 +301,25 @@ noswitch: ...@@ -294,18 +301,25 @@ noswitch:
// during VDSO code we can find the g. // during VDSO code we can find the g.
// If we don't have a signal stack, we won't receive signal, // If we don't have a signal stack, we won't receive signal,
// so don't bother saving g. // so don't bother saving g.
// When using cgo, we already saved g on TLS, also don't save
// g here.
MOVBU runtime·iscgo(SB), R22
CBNZ R22, nosaveg
MOVD m_gsignal(R21), R22 // g.m.gsignal MOVD m_gsignal(R21), R22 // g.m.gsignal
CBZ R22, 3(PC) CBZ R22, nosaveg
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
MOVD g, (R22) MOVD g, (R22)
BL (R2) BL (R2)
CBZ R22, 2(PC) // R22 is unchanged by C code MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
MOVD ZR, (R22) // clear g slot
B finish B finish
nosaveg:
BL (R2)
B finish
fallback: fallback:
MOVD $SYS_clock_gettime, R8 MOVD $SYS_clock_gettime, R8
SVC SVC
......
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