Commit 801bebef authored by Ian Lance Taylor's avatar Ian Lance Taylor

runtime: always install new signal stack on NetBSD and DragonFly

On NetBSD and DragonFly a newly created thread inherits the signal stack
of the creating thread.  That means that in a cgo program a C thread
created using pthread_create will get the signal stack of the creating
thread, most likely a Go thread.  This will then lead to chaos if two
signals occur simultaneously.

We can't fix the general case.  But we can fix the case of a C thread
that calls a Go function, by installing a new signal stack and then
dropping it when we return to C.  That will break the case of a C thread
that calls sigaltstack and then calls Go, because we will drop the C
thread's alternate signal stack as we return from Go.  Still, this is
the 1.5 behavior.  And what else can we do?

Fixes #14051.
Fixes #14052.
Fixes #14067.

Change-Id: Iee286ca50b50ec712a4d929c7121c35e2383a7b9
Reviewed-on: https://go-review.googlesource.com/18835Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: default avatarMikio Hara <mikioh.mikioh@gmail.com>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 3415d0c4
...@@ -140,22 +140,17 @@ func minit() { ...@@ -140,22 +140,17 @@ func minit() {
// m.procid is a uint64, but lwp_start writes an int32. Fix it up. // m.procid is a uint64, but lwp_start writes an int32. Fix it up.
_g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid))) _g_.m.procid = uint64(*(*int32)(unsafe.Pointer(&_g_.m.procid)))
// Initialize signal handling // Initialize signal handling.
var st sigaltstackt
sigaltstack(nil, &st) // On DragonFly a thread created by pthread_create inherits
if st.ss_flags&_SS_DISABLE != 0 { // the signal stack of the creating thread. We always create
// a new signal stack here, to avoid having two Go threads
// using the same signal stack. This breaks the case of a
// thread created in C that calls sigaltstack and then calls a
// Go function, because we will lose track of the C code's
// sigaltstack, but it's the best we can do.
signalstack(&_g_.m.gsignal.stack) signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true _g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_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.newSigstack = false
}
// restore signal mask from m.sigmask and unblock essential signals // restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask nmask := _g_.m.sigmask
......
...@@ -172,22 +172,17 @@ func minit() { ...@@ -172,22 +172,17 @@ func minit() {
_g_ := getg() _g_ := getg()
_g_.m.procid = uint64(lwp_self()) _g_.m.procid = uint64(lwp_self())
// Initialize signal handling // Initialize signal handling.
var st sigaltstackt
sigaltstack(nil, &st) // On NetBSD a thread created by pthread_create inherits the
if st.ss_flags&_SS_DISABLE != 0 { // signal stack of the creating thread. We always create a
// new signal stack here, to avoid having two Go threads using
// the same signal stack. This breaks the case of a thread
// created in C that calls sigaltstack and then calls a Go
// function, because we will lose track of the C code's
// sigaltstack, but it's the best we can do.
signalstack(&_g_.m.gsignal.stack) signalstack(&_g_.m.gsignal.stack)
_g_.m.newSigstack = true _g_.m.newSigstack = true
} else {
// Use existing signal stack.
stsp := uintptr(unsafe.Pointer(st.ss_sp))
_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.newSigstack = false
}
// restore signal mask from m.sigmask and unblock essential signals // restore signal mask from m.sigmask and unblock essential signals
nmask := _g_.m.sigmask nmask := _g_.m.sigmask
......
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