Source File
signal_unix.go
Belonging Package
runtime
package runtime
import (
)
const sigPreempt = _SIGURG
var handlingSig [_NSIG]uint32
var (
disableSigChan chan uint32
enableSigChan chan uint32
maskUpdatedChan chan struct{}
)
func ( bool) {
if fwdSig[] != _SIG_DFL && fwdSig[] != _SIG_IGN {
setsigstack()
} else if fwdSig[] == _SIG_IGN {
sigInitIgnored()
}
continue
}
handlingSig[] = 1
setsig(, funcPC(sighandler))
}
}
if == _SIGPROF {
return
}
:= &sigtable[]
if .flags&_SigNotify != 0 {
ensureSigM()
enableSigChan <-
<-maskUpdatedChan
if atomic.Cas(&handlingSig[], 0, 1) {
atomic.Storeuintptr(&fwdSig[], getsig())
setsig(, funcPC(sighandler))
}
}
}
if == _SIGPROF {
return
}
:= &sigtable[]
if .flags&_SigNotify != 0 {
ensureSigM()
disableSigChan <-
<-maskUpdatedChan
if !sigInstallGoHandler() {
atomic.Store(&handlingSig[], 0)
setsig(, atomic.Loaduintptr(&fwdSig[]))
}
}
}
if == _SIGPROF {
return
}
:= &sigtable[]
if .flags&_SigNotify != 0 {
atomic.Store(&handlingSig[], 0)
setsig(, _SIG_IGN)
}
}
func ( int32) {
if atomic.Cas(&handlingSig[_SIGPROF], 0, 1) {
atomic.Storeuintptr(&fwdSig[_SIGPROF], getsig(_SIGPROF))
setsig(_SIGPROF, funcPC(sighandler))
}
var itimerval
.it_interval.tv_sec = 0
.it_interval.set_usec(1000000 / )
.it_value = .it_interval
setitimer(_ITIMER_PROF, &, nil)
if !sigInstallGoHandler(_SIGPROF) {
if atomic.Cas(&handlingSig[_SIGPROF], 1, 0) {
:= atomic.Loaduintptr(&fwdSig[_SIGPROF])
if == _SIG_DFL {
= _SIG_IGN
}
setsig(_SIGPROF, )
}
}
setitimer(_ITIMER_PROF, &itimerval{}, nil)
}
}
func ( int32) {
getg().m.profilehz =
}
func () {
if signal_ignored(_SIGPIPE) || sigsend(_SIGPIPE) {
return
}
dieFromSignal(_SIGPIPE)
}
if wantAsyncPreempt() {
.pushCall(funcPC(asyncPreempt), )
}
}
atomic.Xadd(&.m.preemptGen, 1)
atomic.Store(&.m.signalPending, 0)
if GOOS == "darwin" || GOOS == "ios" {
atomic.Xadd(&pendingPreemptSignals, -1)
}
}
const preemptMSupported = true
var gsignalStack
:= adjustSignalStack(, .m, &)
if {
.m.gsignal.stktopsp = getcallersp()
}
if .stackguard0 == stackFork {
signalDuringFork()
}
.fixsigcode()
sighandler(, , , )
setg()
if {
restoreGsignalStack(&)
}
}
setg(nil)
needm()
if .ss_flags&_SS_DISABLE != 0 {
noSignalStack()
} else {
sigNotOnStack()
}
dropm()
return false
}
var testSigtrap func(info *siginfo, ctxt *sigctxt, gp *g) bool
var testSigusr1 func(gp *g) bool
func ( uint32, *siginfo, unsafe.Pointer, *g) {
:= getg()
:= &sigctxt{, }
if == _SIGPROF {
sigprof(.sigpc(), .sigsp(), .siglr(), , .m)
return
}
if == _SIGTRAP && testSigtrap != nil && testSigtrap(, (*sigctxt)(noescape(unsafe.Pointer())), ) {
return
}
if == _SIGUSR1 && testSigusr1 != nil && testSigusr1() {
return
}
= _SigThrow
}
= _SigThrow
}
.sig =
.sigcode0 = uintptr(.sigcode())
.sigcode1 = uintptr(.fault())
.sigpc = .sigpc()
.preparePanic(, )
return
}
if .sigcode() == _SI_USER || &_SigNotify != 0 {
if sigsend() {
return
}
}
if .sigcode() == _SI_USER && signal_ignored() {
return
}
if &_SigKill != 0 {
dieFromSignal()
}
if &(_SigThrow|_SigPanic) == 0 {
return
}
.m.throwing = 1
.m.caughtsig.set()
if crashing == 0 {
startpanic_m()
}
if < uint32(len(sigtable)) {
print(sigtable[].name, "\n")
} else {
print("Signal ", , "\n")
}
print("PC=", hex(.sigpc()), " m=", .m.id, " sigcode=", .sigcode(), "\n")
if .m.lockedg != 0 && .m.ncgo > 0 && == .m.g0 {
print("signal arrived during cgo execution\n")
= .m.lockedg.ptr()
}
const = 16
:= .sigpc()
if > physPageSize-%physPageSize {
= physPageSize - %physPageSize
}
print("instruction bytes:")
:= (*[]byte)(unsafe.Pointer())
for := uintptr(0); < ; ++ {
print(" ", hex([]))
}
println()
}
print("\n")
, , := gotraceback()
if > 0 {
goroutineheader()
tracebacktrap(.sigpc(), .sigsp(), .siglr(), )
if .paniconfault {
panicmemAddr(.sigcode1)
}
print("unexpected fault address ", hex(.sigcode1), "\n")
throw("fault")
case _SIGSEGV:
if (.sigcode0 == 0 || .sigcode0 == _SEGV_MAPERR || .sigcode0 == _SEGV_ACCERR) && .sigcode1 < 0x1000 {
panicmem()
if .paniconfault {
panicmemAddr(.sigcode1)
}
print("unexpected fault address ", hex(.sigcode1), "\n")
throw("fault")
case _SIGFPE:
switch .sigcode0 {
case _FPE_INTDIV:
panicdivide()
case _FPE_INTOVF:
panicoverflow()
}
panicfloat()
}
func ( uint32) {
atomic.Store(&handlingSig[], 0)
raise()
exit(2)
}
unblocksig()
setsig(, )
usleep(1000)
setsig(, funcPC(sighandler))
}
if GOOS == "darwin" && GOARCH == "amd64" {
return
}
dieFromSignal(_SIGABRT)
}
func () {
if maskUpdatedChan != nil {
return
}
maskUpdatedChan = make(chan struct{})
disableSigChan = make(chan uint32)
enableSigChan = make(chan uint32)
:= sigset_all
for := range sigtable {
if !blockableSig(uint32()) {
sigdelset(&, )
}
}
sigprocmask(_SIG_SETMASK, &, nil)
for {
select {
case := <-enableSigChan:
if > 0 {
sigdelset(&, int())
}
case := <-disableSigChan:
if > 0 && blockableSig() {
sigaddset(&, int())
}
}
sigprocmask(_SIG_SETMASK, &, nil)
maskUpdatedChan <- struct{}{}
}
}()
}
func ( uint32) {
println("signal", , "received during fork")
throw("signal received during fork")
}
var badginsignalMsg = "fatal: bad g in signal handler\n"
raisebadsignal(uint32(), )
}
dropm()
}
func ( *sigset) {
sigprocmask(_SIG_SETMASK, nil, )
}
func ( sigset) {
sigprocmask(_SIG_SETMASK, &, nil)
}
var sigsetAllExiting = sigset_all
func ( bool) {
if {
sigprocmask(_SIG_SETMASK, &sigsetAllExiting, nil)
return
}
sigprocmask(_SIG_SETMASK, &sigset_all, nil)
}
func ( uint32) {
var sigset
sigaddset(&, int())
sigprocmask(_SIG_UNBLOCK, &, nil)
}
func () {
minitSignalStack()
minitSignalMask()
}
func () {
:= getg()
var stackt
sigaltstack(nil, &)
if .ss_flags&_SS_DISABLE != 0 || !iscgo {
signalstack(&.m.gsignal.stack)
.m.newSigstack = true
} else {
setGsignalStack(&, &.m.goSigStack)
.m.newSigstack = false
}
}
func () {
:= getg().m.sigmask
for := range sigtable {
if !blockableSig(uint32()) {
sigdelset(&, )
}
}
sigprocmask(_SIG_SETMASK, &, nil)
}
func () {
if getg().m.newSigstack {
:= stackt{ss_flags: _SS_DISABLE}
sigaltstack(&, nil)
restoreGsignalStack(&getg().m.goSigStack)
}
}
type gsignalStack struct {
stack stack
stackguard0 uintptr
stackguard1 uintptr
stktopsp uintptr
}
func ( *stackt, *gsignalStack) {
:= getg()
if != nil {
.stack = .m.gsignal.stack
.stackguard0 = .m.gsignal.stackguard0
.stackguard1 = .m.gsignal.stackguard1
.stktopsp = .m.gsignal.stktopsp
}
:= uintptr(unsafe.Pointer(.ss_sp))
.m.gsignal.stack.lo =
.m.gsignal.stack.hi = + .ss_size
.m.gsignal.stackguard0 = + _StackGuard
.m.gsignal.stackguard1 = + _StackGuard
}
func ( *gsignalStack) {
:= getg().m.gsignal
.stack = .stack
.stackguard0 = .stackguard0
.stackguard1 = .stackguard1
.stktopsp = .stktopsp
}
func ( *stack) {
:= stackt{ss_size: .hi - .lo}
setSignalstackSP(&, .lo)
sigaltstack(&, nil)
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |