mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
4f364be08d
commit
d29c14f3d2
1 changed files with 48 additions and 36 deletions
|
|
@ -333,11 +333,39 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If some non-Go code called sigaltstack, adjust.
|
// If some non-Go code called sigaltstack, adjust.
|
||||||
setStack := false
|
|
||||||
var gsignalStack gsignalStack
|
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))
|
sp := uintptr(unsafe.Pointer(&sig))
|
||||||
if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi {
|
if sp >= mp.gsignal.stack.lo && sp < mp.gsignal.stack.hi {
|
||||||
if sp >= g.m.g0.stack.lo && sp < g.m.g0.stack.hi {
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if sp >= mp.g0.stack.lo && sp < mp.g0.stack.hi {
|
||||||
// The signal was delivered on the g0 stack.
|
// The signal was delivered on the g0 stack.
|
||||||
// This can happen when linked with C code
|
// This can happen when linked with C code
|
||||||
// using the thread sanitizer, which collects
|
// 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,
|
// the signal handler directly when C code,
|
||||||
// including C code called via cgo, calls a
|
// including C code called via cgo, calls a
|
||||||
// TSAN-intercepted function such as malloc.
|
// TSAN-intercepted function such as malloc.
|
||||||
st := stackt{ss_size: g.m.g0.stack.hi - g.m.g0.stack.lo}
|
st := stackt{ss_size: mp.g0.stack.hi - mp.g0.stack.lo}
|
||||||
setSignalstackSP(&st, g.m.g0.stack.lo)
|
setSignalstackSP(&st, mp.g0.stack.lo)
|
||||||
setGsignalStack(&st, &gsignalStack)
|
setGsignalStack(&st, gsigStack)
|
||||||
g.m.gsignal.stktopsp = getcallersp()
|
return true
|
||||||
setStack = true
|
}
|
||||||
} else {
|
|
||||||
var st stackt
|
var st stackt
|
||||||
sigaltstack(nil, &st)
|
sigaltstack(nil, &st)
|
||||||
if st.ss_flags&_SS_DISABLE != 0 {
|
if st.ss_flags&_SS_DISABLE != 0 {
|
||||||
|
|
@ -366,24 +394,8 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
||||||
sigNotOnStack(sig)
|
sigNotOnStack(sig)
|
||||||
dropm()
|
dropm()
|
||||||
}
|
}
|
||||||
setGsignalStack(&st, &gsignalStack)
|
setGsignalStack(&st, gsigStack)
|
||||||
g.m.gsignal.stktopsp = getcallersp()
|
return true
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// crashing is the number of m's we have waited for when implementing
|
// crashing is the number of m's we have waited for when implementing
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue