aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_unix.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-11-13 21:01:01 -0500
committerCherry Zhang <cherryyz@google.com>2019-11-15 02:31:52 +0000
commit03c58c9dccde0b9d98962f34e6669a508c8d133a (patch)
tree8738d71ba2bc11ce86005e70bff33b66d30fb023 /src/runtime/signal_unix.go
parent7719016ee297dd4960bb66ed265038f2d75b3c56 (diff)
downloadgo-03c58c9dccde0b9d98962f34e6669a508c8d133a.tar.gz
go-03c58c9dccde0b9d98962f34e6669a508c8d133a.zip
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 <cherryyz@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/signal_unix.go')
-rw-r--r--src/runtime/signal_unix.go11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 35e641286b..f42de36acc 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