github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/runtime/signal_arm.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 darwin dragonfly freebsd linux nacl netbsd openbsd 6 7 package runtime 8 9 import "unsafe" 10 11 func dumpregs(c *sigctxt) { 12 print("trap ", hex(c.trap()), "\n") 13 print("error ", hex(c.error()), "\n") 14 print("oldmask ", hex(c.oldmask()), "\n") 15 print("r0 ", hex(c.r0()), "\n") 16 print("r1 ", hex(c.r1()), "\n") 17 print("r2 ", hex(c.r2()), "\n") 18 print("r3 ", hex(c.r3()), "\n") 19 print("r4 ", hex(c.r4()), "\n") 20 print("r5 ", hex(c.r5()), "\n") 21 print("r6 ", hex(c.r6()), "\n") 22 print("r7 ", hex(c.r7()), "\n") 23 print("r8 ", hex(c.r8()), "\n") 24 print("r9 ", hex(c.r9()), "\n") 25 print("r10 ", hex(c.r10()), "\n") 26 print("fp ", hex(c.fp()), "\n") 27 print("ip ", hex(c.ip()), "\n") 28 print("sp ", hex(c.sp()), "\n") 29 print("lr ", hex(c.lr()), "\n") 30 print("pc ", hex(c.pc()), "\n") 31 print("cpsr ", hex(c.cpsr()), "\n") 32 print("fault ", hex(c.fault()), "\n") 33 } 34 35 func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) { 36 _g_ := getg() 37 c := &sigctxt{info, ctxt} 38 39 if sig == _SIGPROF { 40 sigprof((*byte)(unsafe.Pointer(uintptr(c.pc()))), (*byte)(unsafe.Pointer(uintptr(c.sp()))), (*byte)(unsafe.Pointer(uintptr(c.lr()))), gp, _g_.m) 41 return 42 } 43 44 flags := int32(_SigThrow) 45 if sig < uint32(len(sigtable)) { 46 flags = sigtable[sig].flags 47 } 48 if c.sigcode() != _SI_USER && flags&_SigPanic != 0 { 49 // Make it look like a call to the signal func. 50 // Have to pass arguments out of band since 51 // augmenting the stack frame would break 52 // the unwinding code. 53 gp.sig = sig 54 gp.sigcode0 = uintptr(c.sigcode()) 55 gp.sigcode1 = uintptr(c.fault()) 56 gp.sigpc = uintptr(c.pc()) 57 58 // We arrange lr, and pc to pretend the panicking 59 // function calls sigpanic directly. 60 // Always save LR to stack so that panics in leaf 61 // functions are correctly handled. This smashes 62 // the stack frame but we're not going back there 63 // anyway. 64 sp := c.sp() - 4 65 c.set_sp(sp) 66 *(*uint32)(unsafe.Pointer(uintptr(sp))) = c.lr() 67 68 // Don't bother saving PC if it's zero, which is 69 // probably a call to a nil func: the old link register 70 // is more useful in the stack trace. 71 if gp.sigpc != 0 { 72 c.set_lr(uint32(gp.sigpc)) 73 } 74 75 // In case we are panicking from external C code 76 c.set_r10(uint32(uintptr(unsafe.Pointer(gp)))) 77 c.set_pc(uint32(funcPC(sigpanic))) 78 return 79 } 80 81 if c.sigcode() == _SI_USER || flags&_SigNotify != 0 { 82 if sigsend(sig) { 83 return 84 } 85 } 86 87 if flags&_SigKill != 0 { 88 exit(2) 89 } 90 91 if flags&_SigThrow == 0 { 92 return 93 } 94 95 _g_.m.throwing = 1 96 _g_.m.caughtsig = gp 97 startpanic() 98 99 if sig < uint32(len(sigtable)) { 100 print(sigtable[sig].name, "\n") 101 } else { 102 print("Signal ", sig, "\n") 103 } 104 105 print("PC=", hex(c.pc()), "\n") 106 if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 { 107 print("signal arrived during cgo execution\n") 108 gp = _g_.m.lockedg 109 } 110 print("\n") 111 112 var docrash bool 113 if gotraceback(&docrash) > 0 { 114 goroutineheader(gp) 115 tracebacktrap(uintptr(c.pc()), uintptr(c.sp()), uintptr(c.lr()), gp) 116 tracebackothers(gp) 117 print("\n") 118 dumpregs(c) 119 } 120 121 if docrash { 122 crash() 123 } 124 125 exit(2) 126 }