aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_unix.go
diff options
context:
space:
mode:
authorAndrew G. Morgan <agm@google.com>2020-11-12 21:19:52 -0800
committerIan Lance Taylor <iant@golang.org>2020-12-23 02:10:51 +0000
commitb0b0d9828308368e9fbd59ec5de55801f568f720 (patch)
tree749e40dadc88de8406fa3617592d9a6ac8c64e00 /src/runtime/signal_unix.go
parent223331fc0cf5b23fbb9999eb1164b23695ef612a (diff)
downloadgo-b0b0d9828308368e9fbd59ec5de55801f568f720.tar.gz
go-b0b0d9828308368e9fbd59ec5de55801f568f720.zip
runtime: linux iscgo support for not blocking nptl signals
Under linux+cgo, OS threads are launched via pthread_create(). This abstraction, under linux, requires we avoid blocking signals 32,33 and 34 indefinitely because they are needed to reliably execute POSIX-semantics threading in glibc and/or musl. When blocking signals the go runtime generally re-enables them quickly. However, when a thread exits (under cgo, this is via a return from mstart()), we avoid a deadlock in C-code by not blocking these three signals. Fixes #42494 Change-Id: I02dfb2480a1f97d11679e0c4b132b51bddbe4c14 Reviewed-on: https://go-review.googlesource.com/c/go/+/269799 Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Austin Clements <austin@google.com> Trust: Tobias Klauser <tobias.klauser@gmail.com>
Diffstat (limited to 'src/runtime/signal_unix.go')
-rw-r--r--src/runtime/signal_unix.go19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index e8f39c3321..382ba37a87 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -1042,15 +1042,26 @@ func msigrestore(sigmask sigset) {
sigprocmask(_SIG_SETMASK, &sigmask, nil)
}
-// sigblock blocks all signals in the current thread's signal mask.
+// sigsetAllExiting is used by sigblock(true) when a thread is
+// exiting. sigset_all is defined in OS specific code, and per GOOS
+// behavior may override this default for sigsetAllExiting: see
+// osinit().
+var sigsetAllExiting = sigset_all
+
+// sigblock blocks signals in the current thread's signal mask.
// This is used to block signals while setting up and tearing down g
-// when a non-Go thread calls a Go function.
-// The OS-specific code is expected to define sigset_all.
+// when a non-Go thread calls a Go function. When a thread is exiting
+// we use the sigsetAllExiting value, otherwise the OS specific
+// definition of sigset_all is used.
// This is nosplit and nowritebarrierrec because it is called by needm
// which may be called on a non-Go thread with no g available.
//go:nosplit
//go:nowritebarrierrec
-func sigblock() {
+func sigblock(exiting bool) {
+ if exiting {
+ sigprocmask(_SIG_SETMASK, &sigsetAllExiting, nil)
+ return
+ }
sigprocmask(_SIG_SETMASK, &sigset_all, nil)
}