Commit d29c14f3 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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/+/202446Reviewed-by: default avatarBryan C. Mills <bcmills@google.com>
parent 4f364be0
......@@ -333,11 +333,39 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
}
// If some non-Go code called sigaltstack, adjust.
setStack := false
var gsignalStack gsignalStack
setStack := adjustSignalStack(sig, g.m, &gsignalStack)
if setStack {
g.m.gsignal.stktopsp = getcallersp()
}
setg(g.m.gsignal)
if g.stackguard0 == stackFork {
signalDuringFork(sig)
}
c.fixsigcode(sig)
sighandler(sig, info, ctx, g)
setg(g)
if setStack {
restoreGsignalStack(&gsignalStack)
}
}
// 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 < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi {
if sp >= g.m.g0.stack.lo && sp < g.m.g0.stack.hi {
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
......@@ -345,12 +373,12 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
// 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 {
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 {
......@@ -366,24 +394,8 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
sigNotOnStack(sig)
dropm()
}
setGsignalStack(&st, &gsignalStack)
g.m.gsignal.stktopsp = getcallersp()
setStack = true
}
}
setg(g.m.gsignal)
if g.stackguard0 == stackFork {
signalDuringFork(sig)
}
c.fixsigcode(sig)
sighandler(sig, info, ctx, g)
setg(g)
if setStack {
restoreGsignalStack(&gsignalStack)
}
setGsignalStack(&st, gsigStack)
return true
}
// crashing is the number of m's we have waited for when implementing
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment