aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_unix.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-10-22 02:44:42 -0700
committerIan Lance Taylor <iant@golang.org>2019-10-22 13:57:02 +0000
commitd29c14f3d2519d72a24c7060d99935f562c37db3 (patch)
treeab6ab92c6e65cfc0a1e3a92bbf7be5938194d0ab /src/runtime/signal_unix.go
parent4f364be08de3c5b3d60a134ce9c9d24de834b42d (diff)
downloadgo-d29c14f3d2519d72a24c7060d99935f562c37db3.tar.gz
go-d29c14f3d2519d72a24c7060d99935f562c37db3.zip
runtime: factor signal stack code out of sigtrampgo
This reduces the required nosplit stack size, which permits building on Solaris with -gcflags=all=-N -l. Fixes #35046 Change-Id: Icb3a421bb791c73e2f670ecfadbe32daea79789f Reviewed-on: https://go-review.googlesource.com/c/go/+/202446 Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/runtime/signal_unix.go')
-rw-r--r--src/runtime/signal_unix.go84
1 files changed, 48 insertions, 36 deletions
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 3db6133af0..d5a04b6d48 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -333,43 +333,10 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
}
// If some non-Go code called sigaltstack, adjust.
- setStack := false
var gsignalStack gsignalStack
- sp := uintptr(unsafe.Pointer(&sig))
- if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi {
- if sp >= g.m.g0.stack.lo && sp < g.m.g0.stack.hi {
- // The signal was delivered on the g0 stack.
- // This can happen when linked with C code
- // using the thread sanitizer, which collects
- // signals then delivers them itself by calling
- // the signal handler directly when C code,
- // including C code called via cgo, calls a
- // TSAN-intercepted function such as malloc.
- st := stackt{ss_size: g.m.g0.stack.hi - g.m.g0.stack.lo}
- setSignalstackSP(&st, g.m.g0.stack.lo)
- setGsignalStack(&st, &gsignalStack)
- g.m.gsignal.stktopsp = getcallersp()
- setStack = true
- } else {
- var st stackt
- sigaltstack(nil, &st)
- if st.ss_flags&_SS_DISABLE != 0 {
- setg(nil)
- needm(0)
- noSignalStack(sig)
- dropm()
- }
- stsp := uintptr(unsafe.Pointer(st.ss_sp))
- if sp < stsp || sp >= stsp+st.ss_size {
- setg(nil)
- needm(0)
- sigNotOnStack(sig)
- dropm()
- }
- setGsignalStack(&st, &gsignalStack)
- g.m.gsignal.stktopsp = getcallersp()
- setStack = true
- }
+ setStack := adjustSignalStack(sig, g.m, &gsignalStack)
+ if setStack {
+ g.m.gsignal.stktopsp = getcallersp()
}
setg(g.m.gsignal)
@@ -386,6 +353,51 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
}
}
+// adjustSignalStack adjusts the current stack guard based on the
+// stack pointer that is actually in use while handling a signal.
+// We do this in case some non-Go code called sigaltstack.
+// This reports whether the stack was adjusted, and if so stores the old
+// signal stack in *gsigstack.
+//go:nosplit
+func adjustSignalStack(sig uint32, mp *m, gsigStack *gsignalStack) bool {
+ sp := uintptr(unsafe.Pointer(&sig))
+ if sp >= mp.gsignal.stack.lo && sp < mp.gsignal.stack.hi {
+ return false
+ }
+
+ if sp >= mp.g0.stack.lo && sp < mp.g0.stack.hi {
+ // The signal was delivered on the g0 stack.
+ // This can happen when linked with C code
+ // using the thread sanitizer, which collects
+ // signals then delivers them itself by calling
+ // the signal handler directly when C code,
+ // including C code called via cgo, calls a
+ // TSAN-intercepted function such as malloc.
+ st := stackt{ss_size: mp.g0.stack.hi - mp.g0.stack.lo}
+ setSignalstackSP(&st, mp.g0.stack.lo)
+ setGsignalStack(&st, gsigStack)
+ return true
+ }
+
+ var st stackt
+ sigaltstack(nil, &st)
+ if st.ss_flags&_SS_DISABLE != 0 {
+ setg(nil)
+ needm(0)
+ noSignalStack(sig)
+ dropm()
+ }
+ stsp := uintptr(unsafe.Pointer(st.ss_sp))
+ if sp < stsp || sp >= stsp+st.ss_size {
+ setg(nil)
+ needm(0)
+ sigNotOnStack(sig)
+ dropm()
+ }
+ setGsignalStack(&st, gsigStack)
+ return true
+}
+
// crashing is the number of m's we have waited for when implementing
// GOTRACEBACK=crash when a signal is received.
var crashing int32