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

     1  // Copyright 2009 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 dragonfly linux netbsd
     6  
     7  package runtime
     8  
     9  import "unsafe"
    10  
    11  // Continuation of the (assembly) sigtramp() logic.
    12  // This may be called with the world stopped.
    13  //go:nosplit
    14  //go:nowritebarrierrec
    15  func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
    16  	if sigfwdgo(sig, info, ctx) {
    17  		return
    18  	}
    19  	g := getg()
    20  	if g == nil {
    21  		if sig == _SIGPROF {
    22  			// Ignore profiling signals that arrive on
    23  			// non-Go threads. On some systems they will
    24  			// be handled directly by the signal handler,
    25  			// by calling sigprofNonGo, in which case we won't
    26  			// get here anyhow.
    27  			return
    28  		}
    29  		badsignal(uintptr(sig), &sigctxt{info, ctx})
    30  		return
    31  	}
    32  
    33  	// If some non-Go code called sigaltstack, adjust.
    34  	sp := uintptr(unsafe.Pointer(&sig))
    35  	if sp < g.m.gsignal.stack.lo || sp >= g.m.gsignal.stack.hi {
    36  		var st sigaltstackt
    37  		sigaltstack(nil, &st)
    38  		if st.ss_flags&_SS_DISABLE != 0 {
    39  			setg(nil)
    40  			cgocallback(unsafe.Pointer(funcPC(noSignalStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
    41  		}
    42  		stsp := uintptr(unsafe.Pointer(st.ss_sp))
    43  		if sp < stsp || sp >= stsp+st.ss_size {
    44  			setg(nil)
    45  			cgocallback(unsafe.Pointer(funcPC(sigNotOnStack)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0)
    46  		}
    47  		g.m.gsignal.stack.lo = stsp
    48  		g.m.gsignal.stack.hi = stsp + st.ss_size
    49  		g.m.gsignal.stackguard0 = stsp + _StackGuard
    50  		g.m.gsignal.stackguard1 = stsp + _StackGuard
    51  		g.m.gsignal.stackAlloc = st.ss_size
    52  		g.m.gsignal.stktopsp = getcallersp(unsafe.Pointer(&sig))
    53  	}
    54  
    55  	setg(g.m.gsignal)
    56  	sighandler(sig, info, ctx, g)
    57  	setg(g)
    58  }