From b851e51160bc8ed412e229152b430b75e7ce56f9 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 11 Mar 2020 21:51:09 -0700 Subject: runtime: don't crash on mlock failure Instead, note that mlock has failed, start trying the mitigation of touching the signal stack before sending a preemption signal, and, if the program crashes, mention the possible problem and a wiki page describing the issue (https://golang.org/wiki/LinuxKernelSignalVectorBug). Tested on a kernel in the buggy version range, but with the patch, by using `ulimit -l 0`. Fixes #37436 Change-Id: I072aadb2101496dffd655e442fa5c367dad46ce8 Reviewed-on: https://go-review.googlesource.com/c/go/+/223121 Run-TryBot: Ian Lance Taylor Reviewed-by: Austin Clements Reviewed-by: Keith Randall --- src/runtime/os_linux.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/runtime/os_linux.go') diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go index e0e3f4e341..d8c1827852 100644 --- a/src/runtime/os_linux.go +++ b/src/runtime/os_linux.go @@ -5,6 +5,7 @@ package runtime import ( + "runtime/internal/atomic" "runtime/internal/sys" "unsafe" ) @@ -479,7 +480,21 @@ func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32 func getpid() int func tgkill(tgid, tid, sig int) +// touchStackBeforeSignal stores an errno value. If non-zero, it means +// that we should touch the signal stack before sending a signal. +// This is used on systems that have a bug when the signal stack must +// be faulted in. See #35777 and #37436. +// +// This is accessed atomically as it is set and read in different threads. +// +// TODO(austin): Remove this after Go 1.15 when we remove the +// mlockGsignal workaround. +var touchStackBeforeSignal uint32 + // signalM sends a signal to mp. func signalM(mp *m, sig int) { + if atomic.Load(&touchStackBeforeSignal) != 0 { + atomic.Cas((*uint32)(unsafe.Pointer(mp.gsignal.stack.hi-4)), 0, 0) + } tgkill(getpid(), int(mp.procid), sig) } -- cgit v1.3