]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: crash if a signal is received with bad G and no extra M
authorCherry Zhang <cherryyz@google.com>
Thu, 14 Nov 2019 02:01:01 +0000 (21:01 -0500)
committerCherry Zhang <cherryyz@google.com>
Fri, 15 Nov 2019 02:31:52 +0000 (02:31 +0000)
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>
src/runtime/signal_unix.go

index 35e641286b5fc9e02a176a26b919a3da26c246c9..f42de36acc2fdc1edd92bbae1a007ff39a2bfb4b 100644 (file)
@@ -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