github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/runtime/signal2_unix.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin dragonfly freebsd linux netbsd openbsd
     6  
     7  package runtime
     8  
     9  import "unsafe"
    10  
    11  //go:noescape
    12  func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
    13  
    14  // Determines if the signal should be handled by Go and if not, forwards the
    15  // signal to the handler that was installed before Go's. Returns whether the
    16  // signal was forwarded.
    17  // This is called by the signal handler, and the world may be stopped.
    18  //go:nosplit
    19  //go:nowritebarrierrec
    20  func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
    21  	if sig >= uint32(len(sigtable)) {
    22  		return false
    23  	}
    24  	fwdFn := fwdSig[sig]
    25  
    26  	if !signalsOK {
    27  		// The only way we can get here is if we are in a
    28  		// library or archive, we installed a signal handler
    29  		// at program startup, but the Go runtime has not yet
    30  		// been initialized.
    31  		if fwdFn == _SIG_DFL {
    32  			dieFromSignal(int32(sig))
    33  		} else {
    34  			sigfwd(fwdFn, sig, info, ctx)
    35  		}
    36  		return true
    37  	}
    38  
    39  	flags := sigtable[sig].flags
    40  
    41  	// If there is no handler to forward to, no need to forward.
    42  	if fwdFn == _SIG_DFL {
    43  		return false
    44  	}
    45  
    46  	// If we aren't handling the signal, forward it.
    47  	if flags&_SigHandling == 0 {
    48  		sigfwd(fwdFn, sig, info, ctx)
    49  		return true
    50  	}
    51  
    52  	// Only forward synchronous signals.
    53  	c := &sigctxt{info, ctx}
    54  	if c.sigcode() == _SI_USER || flags&_SigPanic == 0 {
    55  		return false
    56  	}
    57  	// Determine if the signal occurred inside Go code. We test that:
    58  	//   (1) we were in a goroutine (i.e., m.curg != nil), and
    59  	//   (2) we weren't in CGO (i.e., m.curg.syscallsp == 0).
    60  	g := getg()
    61  	if g != nil && g.m != nil && g.m.curg != nil && g.m.curg.syscallsp == 0 {
    62  		return false
    63  	}
    64  	// Signal not handled by Go, forward it.
    65  	if fwdFn != _SIG_IGN {
    66  		sigfwd(fwdFn, sig, info, ctx)
    67  	}
    68  	return true
    69  }