rsc.io/go@v0.0.0-20150416155037-e040fd465409/src/runtime/sigpanic_unix.go (about)

     1  // Copyright 2014 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 solaris
     6  
     7  package runtime
     8  
     9  func sigpanic() {
    10  	g := getg()
    11  	if !canpanic(g) {
    12  		throw("unexpected signal during runtime execution")
    13  	}
    14  
    15  	switch g.sig {
    16  	case _SIGBUS:
    17  		if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault {
    18  			panicmem()
    19  		}
    20  		print("unexpected fault address ", hex(g.sigcode1), "\n")
    21  		throw("fault")
    22  	case _SIGSEGV:
    23  		if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault {
    24  			panicmem()
    25  		}
    26  		print("unexpected fault address ", hex(g.sigcode1), "\n")
    27  		throw("fault")
    28  	case _SIGFPE:
    29  		switch g.sigcode0 {
    30  		case _FPE_INTDIV:
    31  			panicdivide()
    32  		case _FPE_INTOVF:
    33  			panicoverflow()
    34  		}
    35  		panicfloat()
    36  	}
    37  
    38  	if g.sig >= uint32(len(sigtable)) {
    39  		// can't happen: we looked up g.sig in sigtable to decide to call sigpanic
    40  		throw("unexpected signal value")
    41  	}
    42  	panic(errorString(sigtable[g.sig].name))
    43  }
    44  
    45  // setsigsegv is used on darwin/arm{,64} to fake a segmentation fault.
    46  //go:nosplit
    47  func setsigsegv(pc uintptr) {
    48  	g := getg()
    49  	g.sig = _SIGSEGV
    50  	g.sigpc = pc
    51  	g.sigcode0 = _SEGV_MAPERR
    52  	g.sigcode1 = 0 // TODO: emulate si_addr
    53  }