mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: adjust gsignal stack to current signal stack
If non-Go code calls sigaltstack before a signal is received, use sigaltstack to determine the current signal stack and set the gsignal stack to use it. This makes the Go runtime more robust in the face of non-Go code. We still can't handle a disabled signal stack or a signal triggered with SA_ONSTACK clear, but we now give clear errors for those cases. Fixes #7227. Update #9896. Change-Id: Icb1607e01fd6461019b6d77d940e59b3aed4d258 Reviewed-on: https://go-review.googlesource.com/18102 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Mikio Hara <mikioh.mikioh@gmail.com>
This commit is contained in:
parent
e4dcf5c8c2
commit
f7e51c1320
23 changed files with 420 additions and 328 deletions
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type sigTabT struct {
|
||||
flags int32
|
||||
name string
|
||||
|
|
@ -44,3 +46,41 @@ var sigtable = [...]sigTabT{
|
|||
/* 31 */ {_SigNotify, "SIGUSR2: user-defined signal 2"},
|
||||
/* 32 */ {_SigNotify, "SIGTHR: reserved"},
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
|
||||
if sigfwdgo(sig, info, ctx) {
|
||||
return
|
||||
}
|
||||
g := getg()
|
||||
if g == nil {
|
||||
badsignal(uintptr(sig))
|
||||
return
|
||||
}
|
||||
|
||||
// If some non-Go code called sigaltstack, adjust.
|
||||
sp := uintptr(unsafe.Pointer(&sig))
|
||||
if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi {
|
||||
var st stackt
|
||||
sigaltstack(nil, &st)
|
||||
if st.ss_flags&_SS_DISABLE != 0 {
|
||||
setg(nil)
|
||||
cgocallback(unsafe.Pointer(funcPC(noSignalStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
|
||||
}
|
||||
stsp := uintptr(unsafe.Pointer(st.ss_sp))
|
||||
if sp < stsp || sp >= stsp+st.ss_size {
|
||||
setg(nil)
|
||||
cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
|
||||
}
|
||||
g.m.gsignal.stack.lo = stsp
|
||||
g.m.gsignal.stack.hi = stsp + st.ss_size
|
||||
g.m.gsignal.stackguard0 = stsp + _StackGuard
|
||||
g.m.gsignal.stackguard1 = stsp + _StackGuard
|
||||
g.m.gsignal.stackAlloc = st.ss_size
|
||||
g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
|
||||
}
|
||||
|
||||
setg(g.m.gsignal)
|
||||
sighandler(sig, info, ctx, g)
|
||||
setg(g)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue