blob: dde3c7c43faae8082a487660cdc2452757ba3b73 [file] [log] [blame]
Aram Hăvărneanu846ee042015-03-08 14:20:20 +01001// 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
Shenghou Ma4a71b912015-04-10 22:14:43 -04005// +build linux darwin
Aram Hăvărneanu846ee042015-03-08 14:20:20 +01006
7package runtime
8
9import "unsafe"
10
11func 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
Austin Clements9b0ea6a2015-03-24 11:51:24 -040048// May run during STW, so write barriers are not allowed.
49//go:nowritebarrier
Aram Hăvărneanu846ee042015-03-08 14:20:20 +010050func 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
Russ Cox181e26b2015-04-17 00:21:30 -0400111 _g_.m.caughtsig.set(gp)
Aram Hăvărneanu846ee042015-03-08 14:20:20 +0100112 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}