Commit 03c58c9d authored by Cherry Zhang's avatar Cherry Zhang

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: default avatarIan Lance Taylor <iant@golang.org>
parent 7719016e
...@@ -861,11 +861,22 @@ func signalDuringFork(sig uint32) { ...@@ -861,11 +861,22 @@ func signalDuringFork(sig uint32) {
throw("signal received during fork") 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. // This runs on a foreign stack, without an m or a g. No stack split.
//go:nosplit //go:nosplit
//go:norace //go:norace
//go:nowritebarrierrec //go:nowritebarrierrec
func badsignal(sig uintptr, c *sigctxt) { 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) needm(0)
if !sigsend(uint32(sig)) { if !sigsend(uint32(sig)) {
// A foreign thread received the signal sig, and the // A foreign thread received the signal sig, and the
......
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