aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2022-05-11 12:44:06 -0700
committerGopher Robot <gobot@golang.org>2023-09-11 20:10:52 +0000
commit1cdabf0c8b1297a1b82fda975f9313f69b77b262 (patch)
tree68cc35c1c6d8662899ea4c2f04800061d0c3189b /src
parent3556d3b9bfe3ebfc8cd159464e46574e3de8fe7c (diff)
downloadgo-1cdabf0c8b1297a1b82fda975f9313f69b77b262.tar.xz
runtime: avoid staticinit dependency with sigsetAllExiting
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>
Diffstat (limited to 'src')
-rw-r--r--src/runtime/os_linux.go18
-rw-r--r--src/runtime/signal_unix.go32
2 files changed, 28 insertions, 22 deletions
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index 51fedba2b8..26b5ecd1f0 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -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()
}
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 87cb662e41..9a3f18bc14 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -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