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