From 03c58c9dccde0b9d98962f34e6669a508c8d133a Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Wed, 13 Nov 2019 21:01:01 -0500 Subject: [PATCH] runtime: crash if a signal is received with bad G and no extra M When we receive a signal, if G is nil we call badsignal, which calls needm. When cgo is not used, there is no extra M, so needm will just hang. In this situation, even GOTRACEBACK=crash cannot get a stack trace, as we're in the signal handler and cannot receive another signal (SIGQUIT). Instead, just crash. For #35554. Updates #34391. Change-Id: I061ac43fc0ac480435c050083096d126b149d21f Reviewed-on: https://go-review.googlesource.com/c/go/+/206959 Run-TryBot: Cherry Zhang Reviewed-by: Ian Lance Taylor --- src/runtime/signal_unix.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index 35e641286b5..f42de36acc2 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -861,11 +861,22 @@ func signalDuringFork(sig uint32) { throw("signal received during fork") } +var badginsignalMsg = "fatal: bad g in signal handler\n" + // This runs on a foreign stack, without an m or a g. No stack split. //go:nosplit //go:norace //go:nowritebarrierrec func badsignal(sig uintptr, c *sigctxt) { + if !iscgo && !cgoHasExtraM { + // There is no extra M. needm will not be able to grab + // an M. Instead of hanging, just crash. + // Cannot call split-stack function as there is no G. + s := stringStructOf(&badginsignalMsg) + write(2, s.str, int32(s.len)) + exit(2) + *(*uintptr)(unsafe.Pointer(uintptr(123))) = 2 + } needm(0) if !sigsend(uint32(sig)) { // A foreign thread received the signal sig, and the