mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: if we don't handle a signal on a non-Go thread, raise it
In the past badsignal would crash the program. In https://golang.org/cl/10757044 badsignal was changed to call sigsend, to fix issue #3250. The effect of this was that when a non-Go thread received a signal, and os/signal.Notify was not being used to check for occurrences of the signal, the signal was ignored. This changes the code so that if os/signal.Notify is not being used, then the signal handler is reset to what it was, and the signal is raised again. This lets non-Go threads handle the signal as they wish. In particular, it means that a segmentation violation in a non-Go thread will ordinarily crash the process, as it should. Fixes #10139. Update #11794. Change-Id: I2109444aaada9d963ad03b1d071ec667760515e5 Reviewed-on: https://go-review.googlesource.com/12503 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
428ed1e3d9
commit
872b168fe3
26 changed files with 215 additions and 39 deletions
|
|
@ -82,6 +82,19 @@ func TestCgoExternalThreadSIGPROF(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCgoExternalThreadSignal(t *testing.T) {
|
||||||
|
// issue 10139
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "plan9", "windows":
|
||||||
|
t.Skipf("no pthreads on %s", runtime.GOOS)
|
||||||
|
}
|
||||||
|
got := executeTest(t, cgoExternalThreadSignalSource, nil)
|
||||||
|
want := "OK\n"
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("expected %q, but got %q", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCgoDLLImports(t *testing.T) {
|
func TestCgoDLLImports(t *testing.T) {
|
||||||
// test issue 9356
|
// test issue 9356
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
|
|
@ -282,6 +295,60 @@ func main() {
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const cgoExternalThreadSignalSource = `
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
void **nullptr;
|
||||||
|
|
||||||
|
void *crash(void *p) {
|
||||||
|
*nullptr = p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start_crashing_thread(void) {
|
||||||
|
pthread_t tid;
|
||||||
|
return pthread_create(&tid, 0, crash, 0);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) > 1 && os.Args[1] == "crash" {
|
||||||
|
i := C.start_crashing_thread()
|
||||||
|
if i != 0 {
|
||||||
|
fmt.Println("pthread_create failed:", i)
|
||||||
|
// Exit with 0 because parent expects us to crash.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should crash immediately, but give it plenty of
|
||||||
|
// time before failing (by exiting 0) in case we are
|
||||||
|
// running on a slow system.
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := exec.Command(os.Args[0], "crash").CombinedOutput()
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println("C signal did not crash as expected\n")
|
||||||
|
fmt.Printf("%s\n", out)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("OK")
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
const cgoDLLImportsMainSource = `
|
const cgoDLLImportsMainSource = `
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -469,3 +469,8 @@ func signalstack(s *stack) {
|
||||||
func updatesigmask(m sigmask) {
|
func updatesigmask(m sigmask) {
|
||||||
sigprocmask(_SIG_SETMASK, &m[0], nil)
|
sigprocmask(_SIG_SETMASK, &m[0], nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unblocksig(sig int32) {
|
||||||
|
mask := uint32(1) << (uint32(sig) - 1)
|
||||||
|
sigprocmask(_SIG_UNBLOCK, &mask, nil)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var oset sigset
|
var oset sigset
|
||||||
sigprocmask(&sigset_all, &oset)
|
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
|
||||||
|
|
||||||
params := lwpparams{
|
params := lwpparams{
|
||||||
start_func: funcPC(lwp_start),
|
start_func: funcPC(lwp_start),
|
||||||
|
|
@ -91,7 +91,7 @@ func newosproc(mp *m, stk unsafe.Pointer) {
|
||||||
mp.tls[0] = uintptr(mp.id) // XXX so 386 asm can find it
|
mp.tls[0] = uintptr(mp.id) // XXX so 386 asm can find it
|
||||||
|
|
||||||
lwp_create(¶ms)
|
lwp_create(¶ms)
|
||||||
sigprocmask(&oset, nil)
|
sigprocmask(_SIG_SETMASK, &oset, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func osinit() {
|
func osinit() {
|
||||||
|
|
@ -124,7 +124,7 @@ func msigsave(mp *m) {
|
||||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||||
throw("insufficient storage for signal mask")
|
throw("insufficient storage for signal mask")
|
||||||
}
|
}
|
||||||
sigprocmask(nil, smask)
|
sigprocmask(_SIG_SETMASK, nil, smask)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to initialize a new m (including the bootstrap m).
|
// Called to initialize a new m (including the bootstrap m).
|
||||||
|
|
@ -145,14 +145,14 @@ func minit() {
|
||||||
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sigprocmask(&nmask, nil)
|
sigprocmask(_SIG_SETMASK, &nmask, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from dropm to undo the effect of an minit.
|
// Called from dropm to undo the effect of an minit.
|
||||||
func unminit() {
|
func unminit() {
|
||||||
_g_ := getg()
|
_g_ := getg()
|
||||||
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||||
sigprocmask(smask, nil)
|
sigprocmask(_SIG_SETMASK, smask, nil)
|
||||||
signalstack(nil)
|
signalstack(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,5 +237,11 @@ func signalstack(s *stack) {
|
||||||
func updatesigmask(m sigmask) {
|
func updatesigmask(m sigmask) {
|
||||||
var mask sigset
|
var mask sigset
|
||||||
copy(mask.__bits[:], m[:])
|
copy(mask.__bits[:], m[:])
|
||||||
sigprocmask(&mask, nil)
|
sigprocmask(_SIG_SETMASK, &mask, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unblocksig(sig int32) {
|
||||||
|
var mask sigset
|
||||||
|
mask.__bits[(sig-1)/32] |= 1 << ((uint32(sig) - 1) & 31)
|
||||||
|
sigprocmask(_SIG_UNBLOCK, &mask, nil)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,9 @@ func newosproc(mp *m, stk unsafe.Pointer) {
|
||||||
mp.tls[0] = uintptr(mp.id) // so 386 asm can find it
|
mp.tls[0] = uintptr(mp.id) // so 386 asm can find it
|
||||||
|
|
||||||
var oset sigset
|
var oset sigset
|
||||||
sigprocmask(&sigset_all, &oset)
|
sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
|
||||||
thr_new(¶m, int32(unsafe.Sizeof(param)))
|
thr_new(¶m, int32(unsafe.Sizeof(param)))
|
||||||
sigprocmask(&oset, nil)
|
sigprocmask(_SIG_SETMASK, &oset, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func osinit() {
|
func osinit() {
|
||||||
|
|
@ -123,7 +123,7 @@ func msigsave(mp *m) {
|
||||||
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) {
|
||||||
throw("insufficient storage for signal mask")
|
throw("insufficient storage for signal mask")
|
||||||
}
|
}
|
||||||
sigprocmask(nil, smask)
|
sigprocmask(_SIG_SETMASK, nil, smask)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to initialize a new m (including the bootstrap m).
|
// Called to initialize a new m (including the bootstrap m).
|
||||||
|
|
@ -147,14 +147,14 @@ func minit() {
|
||||||
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
nmask.__bits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sigprocmask(&nmask, nil)
|
sigprocmask(_SIG_SETMASK, &nmask, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from dropm to undo the effect of an minit.
|
// Called from dropm to undo the effect of an minit.
|
||||||
func unminit() {
|
func unminit() {
|
||||||
_g_ := getg()
|
_g_ := getg()
|
||||||
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask))
|
||||||
sigprocmask(smask, nil)
|
sigprocmask(_SIG_SETMASK, smask, nil)
|
||||||
signalstack(nil)
|
signalstack(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -239,5 +239,11 @@ func signalstack(s *stack) {
|
||||||
func updatesigmask(m [(_NSIG + 31) / 32]uint32) {
|
func updatesigmask(m [(_NSIG + 31) / 32]uint32) {
|
||||||
var mask sigset
|
var mask sigset
|
||||||
copy(mask.__bits[:], m[:])
|
copy(mask.__bits[:], m[:])
|
||||||
sigprocmask(&mask, nil)
|
sigprocmask(_SIG_SETMASK, &mask, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unblocksig(sig int32) {
|
||||||
|
var mask sigset
|
||||||
|
mask.__bits[(sig-1)/32] |= 1 << ((uint32(sig) - 1) & 31)
|
||||||
|
sigprocmask(_SIG_UNBLOCK, &mask, nil)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -333,3 +333,9 @@ func updatesigmask(m sigmask) {
|
||||||
copy(mask[:], m[:])
|
copy(mask[:], m[:])
|
||||||
rtsigprocmask(_SIG_SETMASK, &mask, nil, int32(unsafe.Sizeof(mask)))
|
rtsigprocmask(_SIG_SETMASK, &mask, nil, int32(unsafe.Sizeof(mask)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unblocksig(sig int32) {
|
||||||
|
var mask sigset
|
||||||
|
mask[(sig-1)/32] |= 1 << ((uint32(sig) - 1) & 31)
|
||||||
|
rtsigprocmask(_SIG_UNBLOCK, &mask, nil, int32(unsafe.Sizeof(mask)))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,10 @@ func badsignal2() {
|
||||||
|
|
||||||
var badsignal1 = []byte("runtime: signal received on thread not created by Go.\n")
|
var badsignal1 = []byte("runtime: signal received on thread not created by Go.\n")
|
||||||
|
|
||||||
|
func raisebadsignal(sig int32) {
|
||||||
|
badsignal2()
|
||||||
|
}
|
||||||
|
|
||||||
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {}
|
func madvise(addr unsafe.Pointer, n uintptr, flags int32) {}
|
||||||
func munmap(addr unsafe.Pointer, n uintptr) {}
|
func munmap(addr unsafe.Pointer, n uintptr) {}
|
||||||
func resetcpuprofiler(hz int32) {}
|
func resetcpuprofiler(hz int32) {}
|
||||||
|
|
|
||||||
|
|
@ -230,3 +230,9 @@ func updatesigmask(m sigmask) {
|
||||||
copy(mask.__bits[:], m[:])
|
copy(mask.__bits[:], m[:])
|
||||||
sigprocmask(_SIG_SETMASK, &mask, nil)
|
sigprocmask(_SIG_SETMASK, &mask, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unblocksig(sig int32) {
|
||||||
|
var mask sigset
|
||||||
|
mask.__bits[(sig-1)/32] |= 1 << ((uint32(sig) - 1) & 31)
|
||||||
|
sigprocmask(_SIG_UNBLOCK, &mask, nil)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -239,3 +239,8 @@ func signalstack(s *stack) {
|
||||||
func updatesigmask(m sigmask) {
|
func updatesigmask(m sigmask) {
|
||||||
sigprocmask(_SIG_SETMASK, m[0])
|
sigprocmask(_SIG_SETMASK, m[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unblocksig(sig int32) {
|
||||||
|
mask := uint32(1) << (uint32(sig) - 1)
|
||||||
|
sigprocmask(_SIG_UNBLOCK, mask)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,10 @@ func badsignal2() {
|
||||||
exits(&_badsignal[0])
|
exits(&_badsignal[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func raisebadsignal(sig int32) {
|
||||||
|
badsignal2()
|
||||||
|
}
|
||||||
|
|
||||||
func _atoi(b []byte) int {
|
func _atoi(b []byte) int {
|
||||||
n := 0
|
n := 0
|
||||||
for len(b) > 0 && '0' <= b[0] && b[0] <= '9' {
|
for len(b) > 0 && '0' <= b[0] && b[0] <= '9' {
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,7 @@ const (
|
||||||
_SI_USER = 0x10001
|
_SI_USER = 0x10001
|
||||||
_SS_DISABLE = 4
|
_SS_DISABLE = 4
|
||||||
_RLIMIT_AS = 10
|
_RLIMIT_AS = 10
|
||||||
|
_SIG_BLOCK = 1
|
||||||
|
_SIG_UNBLOCK = 2
|
||||||
|
_SIG_SETMASK = 3
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,7 @@ const (
|
||||||
_NSIG = 33
|
_NSIG = 33
|
||||||
_SI_USER = 0x10001
|
_SI_USER = 0x10001
|
||||||
_RLIMIT_AS = 10
|
_RLIMIT_AS = 10
|
||||||
|
_SIG_BLOCK = 1
|
||||||
|
_SIG_UNBLOCK = 2
|
||||||
|
_SIG_SETMASK = 3
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ const (
|
||||||
_SS_DISABLE = 2
|
_SS_DISABLE = 2
|
||||||
_NSIG = 65
|
_NSIG = 65
|
||||||
_SI_USER = 0
|
_SI_USER = 0
|
||||||
|
_SIG_BLOCK = 0
|
||||||
|
_SIG_UNBLOCK = 1
|
||||||
_SIG_SETMASK = 2
|
_SIG_SETMASK = 2
|
||||||
_RLIMIT_AS = 9
|
_RLIMIT_AS = 9
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package runtime
|
||||||
|
|
||||||
const (
|
const (
|
||||||
_SS_DISABLE = 2
|
_SS_DISABLE = 2
|
||||||
|
_SIG_UNBLOCK = 2
|
||||||
_SIG_SETMASK = 3
|
_SIG_SETMASK = 3
|
||||||
_NSIG = 73 /* number of signals in sigtable array */
|
_NSIG = 73 /* number of signals in sigtable array */
|
||||||
_SI_USER = 0
|
_SI_USER = 0
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,12 @@ func updatesigmask(m sigmask) {
|
||||||
sigprocmask(_SIG_SETMASK, &mask, nil)
|
sigprocmask(_SIG_SETMASK, &mask, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unblocksig(sig int32) {
|
||||||
|
var mask sigset
|
||||||
|
mask.__sigbits[(sig-1)/32] |= 1 << ((uint32(sig) - 1) & 31)
|
||||||
|
sigprocmask(_SIG_UNBLOCK, &mask, nil)
|
||||||
|
}
|
||||||
|
|
||||||
//go:nosplit
|
//go:nosplit
|
||||||
func semacreate() uintptr {
|
func semacreate() uintptr {
|
||||||
var sem *semt
|
var sem *semt
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ func mach_thread_self() uint32
|
||||||
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
|
func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func sigprocmask(sig uint32, new, old *uint32)
|
func sigprocmask(how uint32, new, old *uint32)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func sigaction(mode uint32, new, old *sigactiont)
|
func sigaction(mode uint32, new, old *sigactiont)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
|
||||||
func sigaction(sig int32, new, old *sigactiont)
|
func sigaction(sig int32, new, old *sigactiont)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func sigprocmask(new, old *sigset)
|
func sigprocmask(how int32, new, old *sigset)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func setitimer(mode int32, new, old *itimerval)
|
func setitimer(mode int32, new, old *itimerval)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
|
||||||
func sigaction(sig int32, new, old *sigactiont)
|
func sigaction(sig int32, new, old *sigactiont)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func sigprocmask(new, old *sigset)
|
func sigprocmask(how int32, new, old *sigset)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func setitimer(mode int32, new, old *itimerval)
|
func setitimer(mode int32, new, old *itimerval)
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ func rtsigprocmask(sig uint32, new, old *sigset, size int32)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func getrlimit(kind int32, limit unsafe.Pointer) int32
|
func getrlimit(kind int32, limit unsafe.Pointer) int32
|
||||||
func raise(sig uint32)
|
func raise(sig int32)
|
||||||
func raiseproc(sig uint32)
|
func raiseproc(sig int32)
|
||||||
|
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
|
func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,43 @@ func sigpipe() {
|
||||||
raise(_SIGPIPE)
|
raise(_SIGPIPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// raisebadsignal is called when a signal is received on a non-Go
|
||||||
|
// thread, and the Go program does not want to handle it (that is, the
|
||||||
|
// program has not called os/signal.Notify for the signal).
|
||||||
|
func raisebadsignal(sig int32) {
|
||||||
|
if sig == _SIGPROF {
|
||||||
|
// Ignore profiling signals that arrive on non-Go threads.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var handler uintptr
|
||||||
|
if sig >= _NSIG {
|
||||||
|
handler = _SIG_DFL
|
||||||
|
} else {
|
||||||
|
handler = fwdSig[sig]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the signal handler and raise the signal.
|
||||||
|
// We are currently running inside a signal handler, so the
|
||||||
|
// signal is blocked. We need to unblock it before raising the
|
||||||
|
// signal, or the signal we raise will be ignored until we return
|
||||||
|
// from the signal handler. We know that the signal was unblocked
|
||||||
|
// before entering the handler, or else we would not have received
|
||||||
|
// it. That means that we don't have to worry about blocking it
|
||||||
|
// again.
|
||||||
|
unblocksig(sig)
|
||||||
|
setsig(sig, handler, false)
|
||||||
|
raise(sig)
|
||||||
|
|
||||||
|
// If the signal didn't cause the program to exit, restore the
|
||||||
|
// Go signal handler and carry on.
|
||||||
|
//
|
||||||
|
// We may receive another instance of the signal before we
|
||||||
|
// restore the Go handler, but that is not so bad: we know
|
||||||
|
// that the Go program has been ignoring the signal.
|
||||||
|
setsig(sig, funcPC(sighandler), true)
|
||||||
|
}
|
||||||
|
|
||||||
func crash() {
|
func crash() {
|
||||||
if GOOS == "darwin" {
|
if GOOS == "darwin" {
|
||||||
// OS X core dumps are linear dumps of the mapped memory,
|
// OS X core dumps are linear dumps of the mapped memory,
|
||||||
|
|
|
||||||
|
|
@ -203,6 +203,12 @@ func sigdisable(sig uint32) {
|
||||||
func sigignore(sig uint32) {
|
func sigignore(sig uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func badsignal2()
|
||||||
|
|
||||||
|
func raisebadsignal(sig int32) {
|
||||||
|
badsignal2()
|
||||||
|
}
|
||||||
|
|
||||||
func crash() {
|
func crash() {
|
||||||
// TODO: This routine should do whatever is needed
|
// TODO: This routine should do whatever is needed
|
||||||
// to make the Windows program abort/crash as it
|
// to make the Windows program abort/crash as it
|
||||||
|
|
|
||||||
|
|
@ -165,5 +165,13 @@ func signal_ignore(s uint32) {
|
||||||
// This runs on a foreign stack, without an m or a g. No stack split.
|
// This runs on a foreign stack, without an m or a g. No stack split.
|
||||||
//go:nosplit
|
//go:nosplit
|
||||||
func badsignal(sig uintptr) {
|
func badsignal(sig uintptr) {
|
||||||
cgocallback(unsafe.Pointer(funcPC(sigsend)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
|
cgocallback(unsafe.Pointer(funcPC(badsignalgo)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
|
||||||
|
}
|
||||||
|
|
||||||
|
func badsignalgo(sig uintptr) {
|
||||||
|
if !sigsend(uint32(sig)) {
|
||||||
|
// A foreign thread received the signal sig, and the
|
||||||
|
// Go code does not want to handle it.
|
||||||
|
raisebadsignal(int32(sig))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -307,9 +307,9 @@ TEXT runtime·osyield(SB),NOSPLIT,$-4
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
|
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
|
||||||
MOVL $3, DI // arg 1 - how (SIG_SETMASK)
|
MOVL how+0(FP), DI // arg 1 - how
|
||||||
MOVQ new+0(FP), SI // arg 2 - set
|
MOVQ new+8(FP), SI // arg 2 - set
|
||||||
MOVQ old+8(FP), DX // arg 3 - oset
|
MOVQ old+16(FP), DX // arg 3 - oset
|
||||||
MOVL $340, AX // sys_sigprocmask
|
MOVL $340, AX // sys_sigprocmask
|
||||||
SYSCALL
|
SYSCALL
|
||||||
JAE 2(PC)
|
JAE 2(PC)
|
||||||
|
|
|
||||||
|
|
@ -355,10 +355,11 @@ TEXT runtime·osyield(SB),NOSPLIT,$-4
|
||||||
|
|
||||||
TEXT runtime·sigprocmask(SB),NOSPLIT,$16
|
TEXT runtime·sigprocmask(SB),NOSPLIT,$16
|
||||||
MOVL $0, 0(SP) // syscall gap
|
MOVL $0, 0(SP) // syscall gap
|
||||||
MOVL $3, 4(SP) // arg 1 - how (SIG_SETMASK)
|
MOVL how+0(FP), AX // arg 1 - how
|
||||||
MOVL new+0(FP), AX
|
MOVL AX, 4(SP)
|
||||||
|
MOVL new+4(FP), AX
|
||||||
MOVL AX, 8(SP) // arg 2 - set
|
MOVL AX, 8(SP) // arg 2 - set
|
||||||
MOVL old+4(FP), AX
|
MOVL old+8(FP), AX
|
||||||
MOVL AX, 12(SP) // arg 3 - oset
|
MOVL AX, 12(SP) // arg 3 - oset
|
||||||
MOVL $340, AX // sys_sigprocmask
|
MOVL $340, AX // sys_sigprocmask
|
||||||
INT $0x80
|
INT $0x80
|
||||||
|
|
|
||||||
|
|
@ -295,9 +295,9 @@ TEXT runtime·osyield(SB),NOSPLIT,$-4
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
|
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
|
||||||
MOVL $3, DI // arg 1 - how (SIG_SETMASK)
|
MOVL how+0(FP), DI // arg 1 - how
|
||||||
MOVQ new+0(FP), SI // arg 2 - set
|
MOVQ new+8(FP), SI // arg 2 - set
|
||||||
MOVQ old+8(FP), DX // arg 3 - oset
|
MOVQ old+16(FP), DX // arg 3 - oset
|
||||||
MOVL $340, AX // sys_sigprocmask
|
MOVL $340, AX // sys_sigprocmask
|
||||||
SYSCALL
|
SYSCALL
|
||||||
JAE 2(PC)
|
JAE 2(PC)
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,9 @@ TEXT runtime·osyield(SB),NOSPLIT,$-4
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
|
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
|
||||||
MOVW $3, R0 // arg 1 - how (SIG_SETMASK)
|
MOVW how+0(FP), R0 // arg 1 - how
|
||||||
MOVW new+0(FP), R1 // arg 2 - set
|
MOVW new+4(FP), R1 // arg 2 - set
|
||||||
MOVW old+4(FP), R2 // arg 3 - oset
|
MOVW old+8(FP), R2 // arg 3 - oset
|
||||||
MOVW $SYS_sigprocmask, R7
|
MOVW $SYS_sigprocmask, R7
|
||||||
SWI $0
|
SWI $0
|
||||||
MOVW.CS $0, R8 // crash on syscall failure
|
MOVW.CS $0, R8 // crash on syscall failure
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-36
|
||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
|
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
|
||||||
MOVQ sig+8(FP), DI
|
MOVL sig+8(FP), DI
|
||||||
MOVQ info+16(FP), SI
|
MOVQ info+16(FP), SI
|
||||||
MOVQ ctx+24(FP), DX
|
MOVQ ctx+24(FP), DX
|
||||||
MOVQ fn+0(FP), AX
|
MOVQ fn+0(FP), AX
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue