Home | History | Annotate | Download | only in runtime
      1 // Copyright 2013 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 amd64 amd64p32
      6 // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
      7 
      8 package runtime
      9 
     10 import (
     11 	"unsafe"
     12 )
     13 
     14 func dumpregs(c *sigctxt) {
     15 	print("rax    ", hex(c.rax()), "\n")
     16 	print("rbx    ", hex(c.rbx()), "\n")
     17 	print("rcx    ", hex(c.rcx()), "\n")
     18 	print("rdx    ", hex(c.rdx()), "\n")
     19 	print("rdi    ", hex(c.rdi()), "\n")
     20 	print("rsi    ", hex(c.rsi()), "\n")
     21 	print("rbp    ", hex(c.rbp()), "\n")
     22 	print("rsp    ", hex(c.rsp()), "\n")
     23 	print("r8     ", hex(c.r8()), "\n")
     24 	print("r9     ", hex(c.r9()), "\n")
     25 	print("r10    ", hex(c.r10()), "\n")
     26 	print("r11    ", hex(c.r11()), "\n")
     27 	print("r12    ", hex(c.r12()), "\n")
     28 	print("r13    ", hex(c.r13()), "\n")
     29 	print("r14    ", hex(c.r14()), "\n")
     30 	print("r15    ", hex(c.r15()), "\n")
     31 	print("rip    ", hex(c.rip()), "\n")
     32 	print("rflags ", hex(c.rflags()), "\n")
     33 	print("cs     ", hex(c.cs()), "\n")
     34 	print("fs     ", hex(c.fs()), "\n")
     35 	print("gs     ", hex(c.gs()), "\n")
     36 }
     37 
     38 var crashing int32
     39 
     40 // May run during STW, so write barriers are not allowed.
     41 //go:nowritebarrier
     42 func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
     43 	_g_ := getg()
     44 	c := &sigctxt{info, ctxt}
     45 
     46 	if sig == _SIGPROF {
     47 		sigprof(uintptr(c.rip()), uintptr(c.rsp()), 0, gp, _g_.m)
     48 		return
     49 	}
     50 
     51 	if GOOS == "darwin" {
     52 		// x86-64 has 48-bit virtual addresses. The top 16 bits must echo bit 47.
     53 		// The hardware delivers a different kind of fault for a malformed address
     54 		// than it does for an attempt to access a valid but unmapped address.
     55 		// OS X 10.9.2 mishandles the malformed address case, making it look like
     56 		// a user-generated signal (like someone ran kill -SEGV ourpid).
     57 		// We pass user-generated signals to os/signal, or else ignore them.
     58 		// Doing that here - and returning to the faulting code - results in an
     59 		// infinite loop. It appears the best we can do is rewrite what the kernel
     60 		// delivers into something more like the truth. The address used below
     61 		// has very little chance of being the one that caused the fault, but it is
     62 		// malformed, it is clearly not a real pointer, and if it does get printed
     63 		// in real life, people will probably search for it and find this code.
     64 		// There are no Google hits for b01dfacedebac1e or 0xb01dfacedebac1e
     65 		// as I type this comment.
     66 		if sig == _SIGSEGV && c.sigcode() == _SI_USER {
     67 			c.set_sigcode(_SI_USER + 1)
     68 			c.set_sigaddr(0xb01dfacedebac1e)
     69 		}
     70 	}
     71 
     72 	flags := int32(_SigThrow)
     73 	if sig < uint32(len(sigtable)) {
     74 		flags = sigtable[sig].flags
     75 	}
     76 	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
     77 		// Make it look like a call to the signal func.
     78 		// Have to pass arguments out of band since
     79 		// augmenting the stack frame would break
     80 		// the unwinding code.
     81 		gp.sig = sig
     82 		gp.sigcode0 = uintptr(c.sigcode())
     83 		gp.sigcode1 = uintptr(c.sigaddr())
     84 		gp.sigpc = uintptr(c.rip())
     85 
     86 		if GOOS == "darwin" {
     87 			// Work around Leopard bug that doesn't set FPE_INTDIV.
     88 			// Look at instruction to see if it is a divide.
     89 			// Not necessary in Snow Leopard (si_code will be != 0).
     90 			if sig == _SIGFPE && gp.sigcode0 == 0 {
     91 				pc := (*[4]byte)(unsafe.Pointer(gp.sigpc))
     92 				i := 0
     93 				if pc[i]&0xF0 == 0x40 { // 64-bit REX prefix
     94 					i++
     95 				} else if pc[i] == 0x66 { // 16-bit instruction prefix
     96 					i++
     97 				}
     98 				if pc[i] == 0xF6 || pc[i] == 0xF7 {
     99 					gp.sigcode0 = _FPE_INTDIV
    100 				}
    101 			}
    102 		}
    103 
    104 		pc := uintptr(c.rip())
    105 		sp := uintptr(c.rsp())
    106 
    107 		// If we don't recognize the PC as code
    108 		// but we do recognize the top pointer on the stack as code,
    109 		// then assume this was a call to non-code and treat like
    110 		// pc == 0, to make unwinding show the context.
    111 		if pc != 0 && findfunc(pc) == nil && findfunc(*(*uintptr)(unsafe.Pointer(sp))) != nil {
    112 			pc = 0
    113 		}
    114 
    115 		// Only push runtime.sigpanic if pc != 0.
    116 		// If pc == 0, probably panicked because of a
    117 		// call to a nil func.  Not pushing that onto sp will
    118 		// make the trace look like a call to runtime.sigpanic instead.
    119 		// (Otherwise the trace will end at runtime.sigpanic and we
    120 		// won't get to see who faulted.)
    121 		if pc != 0 {
    122 			if regSize > ptrSize {
    123 				sp -= ptrSize
    124 				*(*uintptr)(unsafe.Pointer(sp)) = 0
    125 			}
    126 			sp -= ptrSize
    127 			*(*uintptr)(unsafe.Pointer(sp)) = pc
    128 			c.set_rsp(uint64(sp))
    129 		}
    130 		c.set_rip(uint64(funcPC(sigpanic)))
    131 		return
    132 	}
    133 
    134 	if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
    135 		if sigsend(sig) {
    136 			return
    137 		}
    138 	}
    139 
    140 	if flags&_SigKill != 0 {
    141 		exit(2)
    142 	}
    143 
    144 	if flags&_SigThrow == 0 {
    145 		return
    146 	}
    147 
    148 	_g_.m.throwing = 1
    149 	_g_.m.caughtsig.set(gp)
    150 
    151 	if crashing == 0 {
    152 		startpanic()
    153 	}
    154 
    155 	if sig < uint32(len(sigtable)) {
    156 		print(sigtable[sig].name, "\n")
    157 	} else {
    158 		print("Signal ", sig, "\n")
    159 	}
    160 
    161 	print("PC=", hex(c.rip()), " m=", _g_.m.id, "\n")
    162 	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
    163 		print("signal arrived during cgo execution\n")
    164 		gp = _g_.m.lockedg
    165 	}
    166 	print("\n")
    167 
    168 	var docrash bool
    169 	if gotraceback(&docrash) > 0 {
    170 		goroutineheader(gp)
    171 		tracebacktrap(uintptr(c.rip()), uintptr(c.rsp()), 0, gp)
    172 		if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
    173 			// tracebackothers on original m skipped this one; trace it now.
    174 			goroutineheader(_g_.m.curg)
    175 			traceback(^uintptr(0), ^uintptr(0), 0, gp)
    176 		} else if crashing == 0 {
    177 			tracebackothers(gp)
    178 			print("\n")
    179 		}
    180 		dumpregs(c)
    181 	}
    182 
    183 	if docrash {
    184 		crashing++
    185 		if crashing < sched.mcount {
    186 			// There are other m's that need to dump their stacks.
    187 			// Relay SIGQUIT to the next m by sending it to the current process.
    188 			// All m's that have already received SIGQUIT have signal masks blocking
    189 			// receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet.
    190 			// When the last m receives the SIGQUIT, it will fall through to the call to
    191 			// crash below. Just in case the relaying gets botched, each m involved in
    192 			// the relay sleeps for 5 seconds and then does the crash/exit itself.
    193 			// In expected operation, the last m has received the SIGQUIT and run
    194 			// crash/exit and the process is gone, all long before any of the
    195 			// 5-second sleeps have finished.
    196 			print("\n-----\n\n")
    197 			raiseproc(_SIGQUIT)
    198 			usleep(5 * 1000 * 1000)
    199 		}
    200 		crash()
    201 	}
    202 
    203 	exit(2)
    204 }
    205