mirror of
https://github.com/golang/go
synced 2024-11-12 01:50:22 -07:00
runtime: for c-archive/c-shared, install signal handlers synchronously
The previous behaviour of installing the signal handlers in a separate thread meant that Go initialization raced with non-Go initialization if the non-Go initialization also wanted to install signal handlers. Make installing signal handlers synchronous so that the process-wide behavior is predictable. Update #9896. Change-Id: Ice24299877ec46f8518b072a381932d273096a32 Reviewed-on: https://go-review.googlesource.com/18150 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
0b3807a2a3
commit
21b4f234c7
@ -2,15 +2,44 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "p.h"
|
||||
#include "libgo.h"
|
||||
|
||||
static void (*oldHandler)(int, siginfo_t*, void*);
|
||||
|
||||
static void handler(int signo, siginfo_t* info, void* ctxt) {
|
||||
if (oldHandler) {
|
||||
oldHandler(signo, info, ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct sigaction sa;
|
||||
struct sigaction osa;
|
||||
int32_t res;
|
||||
|
||||
// Install our own signal handler.
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_sigaction = handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
|
||||
memset(&osa, 0, sizeof osa);
|
||||
sigemptyset(&osa.sa_mask);
|
||||
if (sigaction(SIGSEGV, &sa, &osa) < 0) {
|
||||
perror("sigaction");
|
||||
return 2;
|
||||
}
|
||||
if (osa.sa_handler == SIG_DFL || (osa.sa_flags&SA_ONSTACK) == 0) {
|
||||
fprintf(stderr, "Go runtime did not install signal handler\n");
|
||||
return 2;
|
||||
}
|
||||
oldHandler = osa.sa_sigaction;
|
||||
|
||||
if (!DidInitRun()) {
|
||||
fprintf(stderr, "ERROR: buildmode=c-archive init should run\n");
|
||||
return 2;
|
||||
@ -21,6 +50,16 @@ int main(void) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Make sure our signal handler is still the one in use.
|
||||
if (sigaction(SIGSEGV, NULL, &sa) < 0) {
|
||||
perror("sigaction check");
|
||||
return 2;
|
||||
}
|
||||
if (sa.sa_sigaction != handler) {
|
||||
fprintf(stderr, "ERROR: wrong signal handler: %p != %p\n", sa.sa_sigaction, handler);
|
||||
return 2;
|
||||
}
|
||||
|
||||
res = FromPkg();
|
||||
if (res != 1024) {
|
||||
fprintf(stderr, "ERROR: FromPkg()=%d, want 1024\n", res);
|
||||
|
@ -172,7 +172,10 @@ When Go code is built with options like -buildmode=c-shared, it will
|
||||
be run as part of an existing non-Go program. The non-Go code may
|
||||
have already installed signal handlers when the Go code starts (that
|
||||
may also happen in unusual cases when using cgo or SWIG; in that case,
|
||||
the discussion here applies).
|
||||
the discussion here applies). For -buildmode=c-archive the Go runtime
|
||||
will initialize signals at global constructor time. For
|
||||
-buildmode=c-shared the Go runtime will initialize signals when the
|
||||
shared library is loaded.
|
||||
|
||||
If the Go runtime sees an existing signal handler for the SIGCANCEL or
|
||||
SIGSETXID signals (which are used only on GNU/Linux), it will turn on
|
||||
|
@ -125,6 +125,15 @@ func newosproc0(stacksize uintptr, fn unsafe.Pointer, fnarg uintptr) {
|
||||
var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
|
||||
var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
|
||||
|
||||
// Called to do synchronous initialization of Go code built with
|
||||
// -buildmode=c-archive or -buildmode=c-shared.
|
||||
// None of the Go runtime is initialized.
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func libpreinit() {
|
||||
initsig(true)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
|
||||
func mpreinit(mp *m) {
|
||||
@ -459,6 +468,8 @@ func memlimit() uintptr {
|
||||
return 0
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i int32, fn uintptr, restart bool) {
|
||||
var sa sigactiont
|
||||
sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
|
||||
@ -471,6 +482,8 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
sigaction(uint32(i), &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsigstack(i int32) {
|
||||
var osa usigactiont
|
||||
sigaction(uint32(i), nil, &osa)
|
||||
@ -486,6 +499,8 @@ func setsigstack(i int32) {
|
||||
sigaction(uint32(i), &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func getsig(i int32) uintptr {
|
||||
var sa usigactiont
|
||||
sigaction(uint32(i), nil, &sa)
|
||||
@ -505,6 +520,8 @@ func signalstack(s *stack) {
|
||||
sigaltstack(&st, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func updatesigmask(m sigmask) {
|
||||
s := sigset(m[0])
|
||||
sigprocmask(_SIG_SETMASK, &s, nil)
|
||||
|
@ -213,6 +213,8 @@ type sigactiont struct {
|
||||
sa_mask sigset
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i int32, fn uintptr, restart bool) {
|
||||
var sa sigactiont
|
||||
sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
|
||||
@ -227,10 +229,14 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
sigaction(i, &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsigstack(i int32) {
|
||||
throw("setsigstack")
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func getsig(i int32) uintptr {
|
||||
var sa sigactiont
|
||||
sigaction(i, nil, &sa)
|
||||
@ -253,6 +259,8 @@ func signalstack(s *stack) {
|
||||
sigaltstack(&st, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func updatesigmask(m sigmask) {
|
||||
var mask sigset
|
||||
copy(mask.__bits[:], m[:])
|
||||
|
@ -220,6 +220,8 @@ type sigactiont struct {
|
||||
sa_mask sigset
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i int32, fn uintptr, restart bool) {
|
||||
var sa sigactiont
|
||||
sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
|
||||
@ -234,10 +236,14 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
sigaction(i, &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsigstack(i int32) {
|
||||
throw("setsigstack")
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func getsig(i int32) uintptr {
|
||||
var sa sigactiont
|
||||
sigaction(i, nil, &sa)
|
||||
@ -260,6 +266,8 @@ func signalstack(s *stack) {
|
||||
sigaltstack(&st, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func updatesigmask(m [(_NSIG + 31) / 32]uint32) {
|
||||
var mask sigset
|
||||
copy(mask.__bits[:], m[:])
|
||||
|
@ -190,6 +190,15 @@ func goenvs() {
|
||||
goenvs_unix()
|
||||
}
|
||||
|
||||
// Called to do synchronous initialization of Go code built with
|
||||
// -buildmode=c-archive or -buildmode=c-shared.
|
||||
// None of the Go runtime is initialized.
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func libpreinit() {
|
||||
initsig(true)
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
|
||||
func mpreinit(mp *m) {
|
||||
@ -298,6 +307,8 @@ func memlimit() uintptr {
|
||||
func sigreturn()
|
||||
func sigtramp()
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i int32, fn uintptr, restart bool) {
|
||||
var sa sigactiont
|
||||
memclr(unsafe.Pointer(&sa), unsafe.Sizeof(sa))
|
||||
@ -316,12 +327,11 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
fn = funcPC(sigtramp)
|
||||
}
|
||||
sa.sa_handler = fn
|
||||
// Qemu rejects rt_sigaction of SIGRTMAX (64).
|
||||
if rt_sigaction(uintptr(i), &sa, nil, unsafe.Sizeof(sa.sa_mask)) != 0 && i != 64 {
|
||||
throw("rt_sigaction failure")
|
||||
}
|
||||
rt_sigaction(uintptr(i), &sa, nil, unsafe.Sizeof(sa.sa_mask))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsigstack(i int32) {
|
||||
var sa sigactiont
|
||||
if rt_sigaction(uintptr(i), nil, &sa, unsafe.Sizeof(sa.sa_mask)) != 0 {
|
||||
@ -336,6 +346,8 @@ func setsigstack(i int32) {
|
||||
}
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func getsig(i int32) uintptr {
|
||||
var sa sigactiont
|
||||
|
||||
@ -362,6 +374,8 @@ func signalstack(s *stack) {
|
||||
sigaltstack(&st, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func updatesigmask(m sigmask) {
|
||||
var mask sigset
|
||||
sigcopyset(&mask, m)
|
||||
|
@ -67,7 +67,7 @@ func goenvs() {
|
||||
goenvs_unix()
|
||||
}
|
||||
|
||||
func initsig() {
|
||||
func initsig(preinit bool) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -206,6 +206,8 @@ type sigactiont struct {
|
||||
sa_flags int32
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i int32, fn uintptr, restart bool) {
|
||||
var sa sigactiont
|
||||
sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
|
||||
@ -220,10 +222,14 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
sigaction(i, &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsigstack(i int32) {
|
||||
throw("setsigstack")
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func getsig(i int32) uintptr {
|
||||
var sa sigactiont
|
||||
sigaction(i, nil, &sa)
|
||||
@ -246,6 +252,8 @@ func signalstack(s *stack) {
|
||||
sigaltstack(&st, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func updatesigmask(m sigmask) {
|
||||
var mask sigset
|
||||
copy(mask.__bits[:], m[:])
|
||||
|
@ -220,6 +220,8 @@ type sigactiont struct {
|
||||
sa_flags int32
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i int32, fn uintptr, restart bool) {
|
||||
var sa sigactiont
|
||||
sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK
|
||||
@ -234,10 +236,14 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
sigaction(i, &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsigstack(i int32) {
|
||||
throw("setsigstack")
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func getsig(i int32) uintptr {
|
||||
var sa sigactiont
|
||||
sigaction(i, nil, &sa)
|
||||
@ -260,6 +266,8 @@ func signalstack(s *stack) {
|
||||
sigaltstack(&st, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func updatesigmask(m sigmask) {
|
||||
sigprocmask(_SIG_SETMASK, sigset(m[0]))
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func getRandomData(r []byte) {
|
||||
func goenvs() {
|
||||
}
|
||||
|
||||
func initsig() {
|
||||
func initsig(preinit bool) {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
|
@ -279,6 +279,8 @@ func memlimit() uintptr {
|
||||
|
||||
func sigtramp()
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsig(i int32, fn uintptr, restart bool) {
|
||||
var sa sigactiont
|
||||
|
||||
@ -295,6 +297,8 @@ func setsig(i int32, fn uintptr, restart bool) {
|
||||
sigaction(i, &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func setsigstack(i int32) {
|
||||
var sa sigactiont
|
||||
sigaction(i, nil, &sa)
|
||||
@ -306,6 +310,8 @@ func setsigstack(i int32) {
|
||||
sigaction(i, &sa, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func getsig(i int32) uintptr {
|
||||
var sa sigactiont
|
||||
sigaction(i, nil, &sa)
|
||||
@ -328,6 +334,8 @@ func signalstack(s *stack) {
|
||||
sigaltstack(&st, nil)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func updatesigmask(m sigmask) {
|
||||
var mask sigset
|
||||
copy(mask.__sigbits[:], m[:])
|
||||
@ -478,6 +486,8 @@ func pthread_create(thread *pthread, attr *pthreadattr, fn uintptr, arg unsafe.P
|
||||
return int32(sysvicall4(&libc_pthread_create, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg)))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func raise(sig int32) /* int32 */ {
|
||||
sysvicall1(&libc_raise, uintptr(sig))
|
||||
}
|
||||
@ -516,6 +526,8 @@ func setitimer(which int32, value *itimerval, ovalue *itimerval) /* int32 */ {
|
||||
sysvicall3(&libc_setitimer, uintptr(which), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(ovalue)))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func sigaction(sig int32, act *sigactiont, oact *sigactiont) /* int32 */ {
|
||||
sysvicall3(&libc_sigaction, uintptr(sig), uintptr(unsafe.Pointer(act)), uintptr(unsafe.Pointer(oact)))
|
||||
}
|
||||
@ -527,6 +539,7 @@ func sigaltstack(ss *sigaltstackt, oss *sigaltstackt) /* int32 */ {
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func sigprocmask(how int32, set *sigset, oset *sigset) /* int32 */ {
|
||||
sysvicall3(&libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset)))
|
||||
}
|
||||
|
@ -1088,7 +1088,7 @@ func mstart1() {
|
||||
cgoHasExtraM = true
|
||||
newextram()
|
||||
}
|
||||
initsig()
|
||||
initsig(false)
|
||||
}
|
||||
|
||||
if fn := _g_.m.mstartfn; fn != nil {
|
||||
|
@ -25,6 +25,10 @@ TEXT _rt0_386_darwin_lib(SB),NOSPLIT,$0
|
||||
MOVL 12(BP), AX
|
||||
MOVL AX, _rt0_386_darwin_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVL $runtime·libpreinit(SB), AX
|
||||
CALL AX
|
||||
|
||||
SUBL $12, SP
|
||||
|
||||
// Create a new thread to do the runtime initialization and return.
|
||||
|
@ -23,6 +23,10 @@ TEXT _rt0_amd64_darwin_lib(SB),NOSPLIT,$0x48
|
||||
MOVQ DI, _rt0_amd64_darwin_lib_argc<>(SB)
|
||||
MOVQ SI, _rt0_amd64_darwin_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVQ $runtime·libpreinit(SB), AX
|
||||
CALL AX
|
||||
|
||||
// Create a new thread to do the runtime initialization and return.
|
||||
MOVQ _cgo_sys_thread_create(SB), AX
|
||||
TESTQ AX, AX
|
||||
|
@ -25,6 +25,10 @@ TEXT _rt0_arm_darwin_lib(SB),NOSPLIT,$0
|
||||
MOVW R0, _rt0_arm_darwin_lib_argc<>(SB)
|
||||
MOVW R1, _rt0_arm_darwin_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVW $runtime·libpreinit(SB), R3
|
||||
CALL (R3)
|
||||
|
||||
// Create a new thread to do the runtime initialization and return.
|
||||
MOVW _cgo_sys_thread_create(SB), R3
|
||||
CMP $0, R3
|
||||
|
@ -25,6 +25,11 @@ TEXT _rt0_arm64_darwin_lib(SB),NOSPLIT,$0
|
||||
|
||||
MOVD R0, _rt0_arm64_darwin_lib_argc<>(SB)
|
||||
MOVD R1, _rt0_arm64_darwin_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVD $runtime·libpreinit(SB), R4
|
||||
BL (R4)
|
||||
|
||||
// Create a new thread to do the runtime initialization and return.
|
||||
MOVD _cgo_sys_thread_create(SB), R4
|
||||
MOVD $_rt0_arm64_darwin_lib_go(SB), R0
|
||||
|
@ -26,6 +26,10 @@ TEXT _rt0_386_linux_lib(SB),NOSPLIT,$0
|
||||
MOVL 12(BP), AX
|
||||
MOVL AX, _rt0_386_linux_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVL $runtime·libpreinit(SB), AX
|
||||
CALL AX
|
||||
|
||||
SUBL $8, SP
|
||||
|
||||
// Create a new thread to do the runtime initialization.
|
||||
|
@ -23,6 +23,10 @@ TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0x48
|
||||
MOVQ DI, _rt0_amd64_linux_lib_argc<>(SB)
|
||||
MOVQ SI, _rt0_amd64_linux_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVQ $runtime·libpreinit(SB), AX
|
||||
CALL AX
|
||||
|
||||
// Create a new thread to do the runtime initialization and return.
|
||||
MOVQ _cgo_sys_thread_create(SB), AX
|
||||
TESTQ AX, AX
|
||||
|
@ -26,6 +26,10 @@ TEXT _rt0_arm_linux_lib(SB),NOSPLIT,$32
|
||||
MOVW R0, _rt0_arm_linux_lib_argc<>(SB)
|
||||
MOVW R1, _rt0_arm_linux_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVW $runtime·libpreinit(SB), R2
|
||||
CALL (R2)
|
||||
|
||||
// Create a new thread to do the runtime initialization.
|
||||
MOVW _cgo_sys_thread_create(SB), R2
|
||||
CMP $0, R2
|
||||
|
@ -20,6 +20,10 @@ TEXT _rt0_arm64_linux_lib(SB),NOSPLIT,$40
|
||||
MOVD R0, _rt0_arm64_linux_lib_argc<>(SB)
|
||||
MOVD R1, _rt0_arm64_linux_lib_argv<>(SB)
|
||||
|
||||
// Synchronous initialization.
|
||||
MOVD $runtime·libpreinit(SB), R4
|
||||
BL (R4)
|
||||
|
||||
// Create a new thread to do the runtime initialization and return.
|
||||
MOVD _cgo_sys_thread_create(SB), R4
|
||||
CMP $0, R4
|
||||
|
@ -34,15 +34,33 @@ var (
|
||||
maskUpdatedChan chan struct{}
|
||||
)
|
||||
|
||||
func initsig() {
|
||||
func init() {
|
||||
// _NSIG is the number of signals on this operating system.
|
||||
// sigtable should describe what to do for all the possible signals.
|
||||
if len(sigtable) != _NSIG {
|
||||
print("runtime: len(sigtable)=", len(sigtable), " _NSIG=", _NSIG, "\n")
|
||||
throw("initsig")
|
||||
throw("bad sigtable len")
|
||||
}
|
||||
}
|
||||
|
||||
var signalsOK bool
|
||||
|
||||
// Initialize signals.
|
||||
// Called by libpreinit so runtime may not be initialized.
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func initsig(preinit bool) {
|
||||
if !preinit {
|
||||
// It's now OK for signal handlers to run.
|
||||
signalsOK = true
|
||||
}
|
||||
|
||||
// For c-archive/c-shared this is called by libpreinit with
|
||||
// preinit == true.
|
||||
if (isarchive || islibrary) && !preinit {
|
||||
return
|
||||
}
|
||||
|
||||
// First call: basic setup.
|
||||
for i := int32(0); i < _NSIG; i++ {
|
||||
t := &sigtable[i]
|
||||
if t.flags == 0 || t.flags&_SigDefault != 0 {
|
||||
@ -64,6 +82,8 @@ func initsig() {
|
||||
}
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func sigInstallGoHandler(sig int32) bool {
|
||||
// For some signals, we respect an inherited SIG_IGN handler
|
||||
// rather than insist on installing our own default handler.
|
||||
@ -101,6 +121,7 @@ func sigenable(sig uint32) {
|
||||
<-maskUpdatedChan
|
||||
if t.flags&_SigHandling == 0 {
|
||||
t.flags |= _SigHandling
|
||||
fwdSig[sig] = getsig(int32(sig))
|
||||
setsig(int32(sig), funcPC(sighandler), true)
|
||||
}
|
||||
}
|
||||
@ -163,6 +184,8 @@ func sigpipe() {
|
||||
// dieFromSignal kills the program with a signal.
|
||||
// This provides the expected exit status for the shell.
|
||||
// This is only called with fatal signals expected to kill the process.
|
||||
//go:nosplit
|
||||
//go:nowritebarrierrec
|
||||
func dieFromSignal(sig int32) {
|
||||
setsig(sig, _SIG_DFL, false)
|
||||
updatesigmask(sigmask{})
|
||||
|
@ -22,6 +22,20 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
|
||||
return false
|
||||
}
|
||||
fwdFn := fwdSig[sig]
|
||||
|
||||
if !signalsOK {
|
||||
// The only way we can get here is if we are in a
|
||||
// library or archive, we installed a signal handler
|
||||
// at program startup, but the Go runtime has not yet
|
||||
// been initialized.
|
||||
if fwdFn == _SIG_DFL {
|
||||
dieFromSignal(int32(sig))
|
||||
} else {
|
||||
sigfwd(fwdFn, sig, info, ctx)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
flags := sigtable[sig].flags
|
||||
|
||||
// If there is no handler to forward to, no need to forward.
|
||||
|
@ -191,7 +191,7 @@ func setBadSignalMsg() {
|
||||
|
||||
// Following are not implemented.
|
||||
|
||||
func initsig() {
|
||||
func initsig(preinit bool) {
|
||||
}
|
||||
|
||||
func sigenable(sig uint32) {
|
||||
|
Loading…
Reference in New Issue
Block a user