rsc.io/go@v0.0.0-20150416155037-e040fd465409/src/runtime/signal_arm64.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 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 // May run during STW, so write barriers are not allowed. 49 //go:nowritebarrier 50 func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) { 51 _g_ := getg() 52 c := &sigctxt{info, ctxt} 53 54 if sig == _SIGPROF { 55 sigprof(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp, _g_.m) 56 return 57 } 58 59 flags := int32(_SigThrow) 60 if sig < uint32(len(sigtable)) { 61 flags = sigtable[sig].flags 62 } 63 if c.sigcode() != _SI_USER && flags&_SigPanic != 0 { 64 // Make it look like a call to the signal func. 65 // Have to pass arguments out of band since 66 // augmenting the stack frame would break 67 // the unwinding code. 68 gp.sig = sig 69 gp.sigcode0 = uintptr(c.sigcode()) 70 gp.sigcode1 = uintptr(c.fault()) 71 gp.sigpc = uintptr(c.pc()) 72 73 // We arrange lr, and pc to pretend the panicking 74 // function calls sigpanic directly. 75 // Always save LR to stack so that panics in leaf 76 // functions are correctly handled. This smashes 77 // the stack frame but we're not going back there 78 // anyway. 79 sp := c.sp() - spAlign // needs only sizeof uint64, but must align the stack 80 c.set_sp(sp) 81 *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr() 82 83 // Don't bother saving PC if it's zero, which is 84 // probably a call to a nil func: the old link register 85 // is more useful in the stack trace. 86 if gp.sigpc != 0 { 87 c.set_lr(uint64(gp.sigpc)) 88 } 89 90 // In case we are panicking from external C code 91 c.set_r28(uint64(uintptr(unsafe.Pointer(gp)))) 92 c.set_pc(uint64(funcPC(sigpanic))) 93 return 94 } 95 96 if c.sigcode() == _SI_USER || flags&_SigNotify != 0 { 97 if sigsend(sig) { 98 return 99 } 100 } 101 102 if flags&_SigKill != 0 { 103 exit(2) 104 } 105 106 if flags&_SigThrow == 0 { 107 return 108 } 109 110 _g_.m.throwing = 1 111 setGNoWriteBarrier(&_g_.m.caughtsig, gp) 112 startpanic() 113 114 if sig < uint32(len(sigtable)) { 115 print(sigtable[sig].name, "\n") 116 } else { 117 print("Signal ", sig, "\n") 118 } 119 120 print("PC=", hex(c.pc()), "\n") 121 if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 { 122 print("signal arrived during cgo execution\n") 123 gp = _g_.m.lockedg 124 } 125 print("\n") 126 127 var docrash bool 128 if gotraceback(&docrash) > 0 { 129 goroutineheader(gp) 130 tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp) 131 tracebackothers(gp) 132 print("\n") 133 dumpregs(c) 134 } 135 136 if docrash { 137 crash() 138 } 139 140 exit(2) 141 }