Skip to content

Commit f07cbc7

Browse files
committed
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 <[email protected]>
1 parent fb05264 commit f07cbc7

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

src/runtime/signal_unix.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,11 @@ func preemptM(mp *m) {
360360
func sigFetchG(c *sigctxt) *g {
361361
switch GOARCH {
362362
case "arm", "arm64":
363-
if inVDSOPage(c.sigpc()) {
364-
// Before making a VDSO call we save the g to the bottom of the
365-
// signal stack. Fetch from there.
363+
if !iscgo && inVDSOPage(c.sigpc()) {
364+
// When using cgo, we save the g on TLS and load it from there
365+
// in sigtramp. Just use that.
366+
// Otherwise, before making a VDSO call we save the g to the
367+
// bottom of the signal stack. Fetch from there.
366368
// TODO: in efence mode, stack is sysAlloc'd, so this wouldn't
367369
// work.
368370
sp := getcallersp()

src/runtime/sys_linux_arm.s

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,21 +277,28 @@ noswitch:
277277
// during VDSO code we can find the g.
278278
// If we don't have a signal stack, we won't receive signal,
279279
// so don't bother saving g.
280+
// When using cgo, we already saved g on TLS, also don't save
281+
// g here.
282+
MOVB runtime·iscgo(SB), R6
283+
CMP $0, R6
284+
BNE nosaveg
280285
MOVW m_gsignal(R5), R6 // g.m.gsignal
281286
CMP $0, R6
282-
BEQ 3(PC)
287+
BEQ nosaveg
283288
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
284289
MOVW g, (R6)
285290

286291
BL (R11)
287292

288-
CMP $0, R6 // R6 is unchanged by C code
289-
BEQ 3(PC)
290293
MOVW $0, R1
291-
MOVW R1, (R6) // clear g slot
294+
MOVW R1, (R6) // clear g slot, R6 is unchanged by C code
292295

293296
JMP finish
294297

298+
nosaveg:
299+
BL (R11)
300+
JMP finish
301+
295302
fallback:
296303
MOVW $SYS_clock_gettime, R7
297304
SWI $0
@@ -344,21 +351,28 @@ noswitch:
344351
// during VDSO code we can find the g.
345352
// If we don't have a signal stack, we won't receive signal,
346353
// so don't bother saving g.
354+
// When using cgo, we already saved g on TLS, also don't save
355+
// g here.
356+
MOVB runtime·iscgo(SB), R6
357+
CMP $0, R6
358+
BNE nosaveg
347359
MOVW m_gsignal(R5), R6 // g.m.gsignal
348360
CMP $0, R6
349-
BEQ 3(PC)
361+
BEQ nosaveg
350362
MOVW (g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
351363
MOVW g, (R6)
352364

353365
BL (R11)
354366

355-
CMP $0, R6 // R6 is unchanged by C code
356-
BEQ 3(PC)
357367
MOVW $0, R1
358-
MOVW R1, (R6) // clear g slot
368+
MOVW R1, (R6) // clear g slot, R6 is unchanged by C code
359369

360370
JMP finish
361371

372+
nosaveg:
373+
BL (R11)
374+
JMP finish
375+
362376
fallback:
363377
MOVW $SYS_clock_gettime, R7
364378
SWI $0

src/runtime/sys_linux_arm64.s

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,18 +237,25 @@ noswitch:
237237
// during VDSO code we can find the g.
238238
// If we don't have a signal stack, we won't receive signal,
239239
// so don't bother saving g.
240+
// When using cgo, we already saved g on TLS, also don't save
241+
// g here.
242+
MOVBU runtime·iscgo(SB), R22
243+
CBNZ R22, nosaveg
240244
MOVD m_gsignal(R21), R22 // g.m.gsignal
241-
CBZ R22, 3(PC)
245+
CBZ R22, nosaveg
242246
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
243247
MOVD g, (R22)
244248

245249
BL (R2)
246250

247-
CBZ R22, 2(PC) // R22 is unchanged by C code
248-
MOVD ZR, (R22) // clear g slot
251+
MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
249252

250253
B finish
251254

255+
nosaveg:
256+
BL (R2)
257+
B finish
258+
252259
fallback:
253260
MOVD $SYS_clock_gettime, R8
254261
SVC
@@ -294,18 +301,25 @@ noswitch:
294301
// during VDSO code we can find the g.
295302
// If we don't have a signal stack, we won't receive signal,
296303
// so don't bother saving g.
304+
// When using cgo, we already saved g on TLS, also don't save
305+
// g here.
306+
MOVBU runtime·iscgo(SB), R22
307+
CBNZ R22, nosaveg
297308
MOVD m_gsignal(R21), R22 // g.m.gsignal
298-
CBZ R22, 3(PC)
309+
CBZ R22, nosaveg
299310
MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
300311
MOVD g, (R22)
301312

302313
BL (R2)
303314

304-
CBZ R22, 2(PC) // R22 is unchanged by C code
305-
MOVD ZR, (R22) // clear g slot
315+
MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
306316

307317
B finish
308318

319+
nosaveg:
320+
BL (R2)
321+
B finish
322+
309323
fallback:
310324
MOVD $SYS_clock_gettime, R8
311325
SVC

0 commit comments

Comments
 (0)