Skip to content

Commit 03c58c9

Browse files
committed
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 <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 7719016 commit 03c58c9

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/runtime/signal_unix.go

+11
Original file line numberDiff line numberDiff line change
@@ -861,11 +861,22 @@ func signalDuringFork(sig uint32) {
861861
throw("signal received during fork")
862862
}
863863

864+
var badginsignalMsg = "fatal: bad g in signal handler\n"
865+
864866
// This runs on a foreign stack, without an m or a g. No stack split.
865867
//go:nosplit
866868
//go:norace
867869
//go:nowritebarrierrec
868870
func badsignal(sig uintptr, c *sigctxt) {
871+
if !iscgo && !cgoHasExtraM {
872+
// There is no extra M. needm will not be able to grab
873+
// an M. Instead of hanging, just crash.
874+
// Cannot call split-stack function as there is no G.
875+
s := stringStructOf(&badginsignalMsg)
876+
write(2, s.str, int32(s.len))
877+
exit(2)
878+
*(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
879+
}
869880
needm(0)
870881
if !sigsend(uint32(sig)) {
871882
// A foreign thread received the signal sig, and the

0 commit comments

Comments
 (0)