]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: avoid staticinit dependency with sigsetAllExiting
authorMatthew Dempsky <mdempsky@google.com>
Wed, 11 May 2022 19:44:06 +0000 (12:44 -0700)
committerGopher Robot <gobot@golang.org>
Mon, 11 Sep 2023 20:10:52 +0000 (20:10 +0000)
Currently, package runtime runs `osinit` before dynamic initialization
of package-scope variables; but on GOOS=linux, `osinit` involves
mutating `sigsetAllExiting`.

This currently works because cmd/compile and gccgo have
non-spec-conforming optimizations that statically initialize
`sigsetAllExiting`, but disabling that optimization causes
`sigsetAllExiting` to be dynamically initialized instead. This in turn
causes the mutations in `osinit` to get lost.

This CL moves the initialization of `sigsetAllExiting` from `osinit`
into its initialization expression, and then removes the special case
for continuing to perform the static-initialization optimization for
package runtime.

Updates #51913.

Change-Id: I3be31454277c103372c9701d227dc774b2311dad
Reviewed-on: https://go-review.googlesource.com/c/go/+/405549
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/runtime/os_linux.go
src/runtime/signal_unix.go

index 51fedba2b874279de02dcd391be07f1016e901a0..26b5ecd1f0586fc4b9902e36eb2bea0d64785297 100644 (file)
@@ -346,24 +346,6 @@ func getHugePageSize() uintptr {
 func osinit() {
        ncpu = getproccount()
        physHugePageSize = getHugePageSize()
-       if iscgo {
-               // #42494 glibc and musl reserve some signals for
-               // internal use and require they not be blocked by
-               // the rest of a normal C runtime. When the go runtime
-               // blocks...unblocks signals, temporarily, the blocked
-               // interval of time is generally very short. As such,
-               // these expectations of *libc code are mostly met by
-               // the combined go+cgo system of threads. However,
-               // when go causes a thread to exit, via a return from
-               // mstart(), the combined runtime can deadlock if
-               // these signals are blocked. Thus, don't block these
-               // signals when exiting threads.
-               // - glibc: SIGCANCEL (32), SIGSETXID (33)
-               // - musl: SIGTIMER (32), SIGCANCEL (33), SIGSYNCCALL (34)
-               sigdelset(&sigsetAllExiting, 32)
-               sigdelset(&sigsetAllExiting, 33)
-               sigdelset(&sigsetAllExiting, 34)
-       }
        osArchInit()
 }
 
index 87cb662e416aad712cd0fa61b7075f43791db2ed..9a3f18bc14d770a429b943db8dcfc6389e8ecbf1 100644 (file)
@@ -1177,10 +1177,34 @@ func msigrestore(sigmask sigset) {
 }
 
 // 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
+// exiting.
+var sigsetAllExiting = func() sigset {
+       res := sigset_all
+
+       // Apply GOOS-specific overrides here, rather than in osinit,
+       // because osinit may be called before sigsetAllExiting is
+       // initialized (#51913).
+       if GOOS == "linux" && iscgo {
+               // #42494 glibc and musl reserve some signals for
+               // internal use and require they not be blocked by
+               // the rest of a normal C runtime. When the go runtime
+               // blocks...unblocks signals, temporarily, the blocked
+               // interval of time is generally very short. As such,
+               // these expectations of *libc code are mostly met by
+               // the combined go+cgo system of threads. However,
+               // when go causes a thread to exit, via a return from
+               // mstart(), the combined runtime can deadlock if
+               // these signals are blocked. Thus, don't block these
+               // signals when exiting threads.
+               // - glibc: SIGCANCEL (32), SIGSETXID (33)
+               // - musl: SIGTIMER (32), SIGCANCEL (33), SIGSYNCCALL (34)
+               sigdelset(&res, 32)
+               sigdelset(&res, 33)
+               sigdelset(&res, 34)
+       }
+
+       return res
+}()
 
 // sigblock blocks signals in the current thread's signal mask.
 // This is used to block signals while setting up and tearing down g