Home | History | Annotate | Download | only in runtime
      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 linux darwin
      6 
      7 package runtime
      8 
      9 import "unsafe"
     10 
     11 func dumpregs(c *sigctxt) {
     12 	print("r0      ", hex(c.r0()), "\n")
     13 	print("r1      ", hex(c.r1()), "\n")
     14 	print("r2      ", hex(c.r2()), "\n")
     15 	print("r3      ", hex(c.r3()), "\n")
     16 	print("r4      ", hex(c.r4()), "\n")
     17 	print("r5      ", hex(c.r5()), "\n")
     18 	print("r6      ", hex(c.r6()), "\n")
     19 	print("r7      ", hex(c.r7()), "\n")
     20 	print("r8      ", hex(c.r8()), "\n")
     21 	print("r9      ", hex(c.r9()), "\n")
     22 	print("r10     ", hex(c.r10()), "\n")
     23 	print("r11     ", hex(c.r11()), "\n")
     24 	print("r12     ", hex(c.r12()), "\n")
     25 	print("r13     ", hex(c.r13()), "\n")
     26 	print("r14     ", hex(c.r14()), "\n")
     27 	print("r15     ", hex(c.r15()), "\n")
     28 	print("r16     ", hex(c.r16()), "\n")
     29 	print("r17     ", hex(c.r17()), "\n")
     30 	print("r18     ", hex(c.r18()), "\n")
     31 	print("r19     ", hex(c.r19()), "\n")
     32 	print("r20     ", hex(c.r20()), "\n")
     33 	print("r21     ", hex(c.r21()), "\n")
     34 	print("r22     ", hex(c.r22()), "\n")
     35 	print("r23     ", hex(c.r23()), "\n")
     36 	print("r24     ", hex(c.r24()), "\n")
     37 	print("r25     ", hex(c.r25()), "\n")
     38 	print("r26     ", hex(c.r26()), "\n")
     39 	print("r27     ", hex(c.r27()), "\n")
     40 	print("r28     ", hex(c.r28()), "\n")
     41 	print("r29     ", hex(c.r29()), "\n")
     42 	print("lr      ", hex(c.lr()), "\n")
     43 	print("sp      ", hex(c.sp()), "\n")
     44 	print("pc      ", hex(c.pc()), "\n")
     45 	print("fault   ", hex(c.fault()), "\n")
     46 }
     47 
     48 var crashing int32
     49 
     50 // May run during STW, so write barriers are not allowed.
     51 //go:nowritebarrier
     52 func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
     53 	_g_ := getg()
     54 	c := &sigctxt{info, ctxt}
     55 
     56 	if sig == _SIGPROF {
     57 		sigprof(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp, _g_.m)
     58 		return
     59 	}
     60 
     61 	flags := int32(_SigThrow)
     62 	if sig < uint32(len(sigtable)) {
     63 		flags = sigtable[sig].flags
     64 	}
     65 	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
     66 		// Make it look like a call to the signal func.
     67 		// Have to pass arguments out of band since
     68 		// augmenting the stack frame would break
     69 		// the unwinding code.
     70 		gp.sig = sig
     71 		gp.sigcode0 = uintptr(c.sigcode())
     72 		gp.sigcode1 = uintptr(c.fault())
     73 		gp.sigpc = uintptr(c.pc())
     74 
     75 		// We arrange lr, and pc to pretend the panicking
     76 		// function calls sigpanic directly.
     77 		// Always save LR to stack so that panics in leaf
     78 		// functions are correctly handled. This smashes
     79 		// the stack frame but we're not going back there
     80 		// anyway.
     81 		sp := c.sp() - spAlign // needs only sizeof uint64, but must align the stack
     82 		c.set_sp(sp)
     83 		*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()
     84 
     85 		pc := uintptr(gp.sigpc)
     86 
     87 		// If we don't recognize the PC as code
     88 		// but we do recognize the link register as code,
     89 		// then assume this was a call to non-code and treat like
     90 		// pc == 0, to make unwinding show the context.
     91 		if pc != 0 && findfunc(pc) == nil && findfunc(uintptr(c.lr())) != nil {
     92 			pc = 0
     93 		}
     94 
     95 		// Don't bother saving PC if it's zero, which is
     96 		// probably a call to a nil func: the old link register
     97 		// is more useful in the stack trace.
     98 		if pc != 0 {
     99 			c.set_lr(uint64(pc))
    100 		}
    101 
    102 		// In case we are panicking from external C code
    103 		c.set_r28(uint64(uintptr(unsafe.Pointer(gp))))
    104 		c.set_pc(uint64(funcPC(sigpanic)))
    105 		return
    106 	}
    107 
    108 	if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
    109 		if sigsend(sig) {
    110 			return
    111 		}
    112 	}
    113 
    114 	if flags&_SigKill != 0 {
    115 		exit(2)
    116 	}
    117 
    118 	if flags&_SigThrow == 0 {
    119 		return
    120 	}
    121 
    122 	_g_.m.throwing = 1
    123 	_g_.m.caughtsig.set(gp)
    124 
    125 	if crashing == 0 {
    126 		startpanic()
    127 	}
    128 
    129 	if sig < uint32(len(sigtable)) {
    130 		print(sigtable[sig].name, "\n")
    131 	} else {
    132 		print("Signal ", sig, "\n")
    133 	}
    134 
    135 	print("PC=", hex(c.pc()), " m=", _g_.m.id, "\n")
    136 	if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
    137 		print("signal arrived during cgo execution\n")
    138 		gp = _g_.m.lockedg
    139 	}
    140 	print("\n")
    141 
    142 	var docrash bool
    143 	if gotraceback(&docrash) > 0 {
    144 		goroutineheader(gp)
    145 		tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp)
    146 		if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
    147 			// tracebackothers on original m skipped this one; trace it now.
    148 			goroutineheader(_g_.m.curg)
    149 			traceback(^uintptr(0), ^uintptr(0), 0, gp)
    150 		} else if crashing == 0 {
    151 			tracebackothers(gp)
    152 			print("\n")
    153 		}
    154 		dumpregs(c)
    155 	}
    156 
    157 	if docrash {
    158 		crashing++
    159 		if crashing < sched.mcount {
    160 			// There are other m's that need to dump their stacks.
    161 			// Relay SIGQUIT to the next m by sending it to the current process.
    162 			// All m's that have already received SIGQUIT have signal masks blocking
    163 			// receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet.
    164 			// When the last m receives the SIGQUIT, it will fall through to the call to
    165 			// crash below. Just in case the relaying gets botched, each m involved in
    166 			// the relay sleeps for 5 seconds and then does the crash/exit itself.
    167 			// In expected operation, the last m has received the SIGQUIT and run
    168 			// crash/exit and the process is gone, all long before any of the
    169 			// 5-second sleeps have finished.
    170 			print("\n-----\n\n")
    171 			raiseproc(_SIGQUIT)
    172 			usleep(5 * 1000 * 1000)
    173 		}
    174 		crash()
    175 	}
    176 
    177 	exit(2)
    178 }
    179