github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/os3_plan9.go (about) 1 // Copyright 2010 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 package runtime 6 7 import ( 8 "internal/abi" 9 "internal/goarch" 10 "unsafe" 11 ) 12 13 // May run during STW, so write barriers are not allowed. 14 // 15 //go:nowritebarrierrec 16 func sighandler(_ureg *ureg, note *byte, gp *g) int { 17 gsignal := getg() 18 mp := gsignal.m 19 20 var t sigTabT 21 var docrash bool 22 var sig int 23 var flags int 24 var level int32 25 26 c := &sigctxt{_ureg} 27 notestr := gostringnocopy(note) 28 29 // The kernel will never pass us a nil note or ureg so we probably 30 // made a mistake somewhere in sigtramp. 31 if _ureg == nil || note == nil { 32 print("sighandler: ureg ", _ureg, " note ", note, "\n") 33 goto Throw 34 } 35 // Check that the note is no more than ERRMAX bytes (including 36 // the trailing NUL). We should never receive a longer note. 37 if len(notestr) > _ERRMAX-1 { 38 print("sighandler: note is longer than ERRMAX\n") 39 goto Throw 40 } 41 if isAbortPC(c.pc()) { 42 // Never turn abort into a panic. 43 goto Throw 44 } 45 // See if the note matches one of the patterns in sigtab. 46 // Notes that do not match any pattern can be handled at a higher 47 // level by the program but will otherwise be ignored. 48 flags = _SigNotify 49 for sig, t = range sigtable { 50 if hasPrefix(notestr, t.name) { 51 flags = t.flags 52 break 53 } 54 } 55 if flags&_SigPanic != 0 && gp.throwsplit { 56 // We can't safely sigpanic because it may grow the 57 // stack. Abort in the signal handler instead. 58 flags = (flags &^ _SigPanic) | _SigThrow 59 } 60 if flags&_SigGoExit != 0 { 61 exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix. 62 } 63 if flags&_SigPanic != 0 { 64 // Copy the error string from sigtramp's stack into m->notesig so 65 // we can reliably access it from the panic routines. 66 memmove(unsafe.Pointer(mp.notesig), unsafe.Pointer(note), uintptr(len(notestr)+1)) 67 gp.sig = uint32(sig) 68 gp.sigpc = c.pc() 69 70 pc := c.pc() 71 sp := c.sp() 72 73 // If we don't recognize the PC as code 74 // but we do recognize the top pointer on the stack as code, 75 // then assume this was a call to non-code and treat like 76 // pc == 0, to make unwinding show the context. 77 if pc != 0 && !findfunc(pc).valid() && findfunc(*(*uintptr)(unsafe.Pointer(sp))).valid() { 78 pc = 0 79 } 80 81 // IF LR exists, sigpanictramp must save it to the stack 82 // before entry to sigpanic so that panics in leaf 83 // functions are correctly handled. This will smash 84 // the stack frame but we're not going back there 85 // anyway. 86 if usesLR { 87 c.savelr(c.lr()) 88 } 89 90 // If PC == 0, probably panicked because of a call to a nil func. 91 // Not faking that as the return address will make the trace look like a call 92 // to sigpanic instead. (Otherwise the trace will end at 93 // sigpanic and we won't get to see who faulted). 94 if pc != 0 { 95 if usesLR { 96 c.setlr(pc) 97 } else { 98 sp -= goarch.PtrSize 99 *(*uintptr)(unsafe.Pointer(sp)) = pc 100 c.setsp(sp) 101 } 102 } 103 if usesLR { 104 c.setpc(abi.FuncPCABI0(sigpanictramp)) 105 } else { 106 c.setpc(abi.FuncPCABI0(sigpanic0)) 107 } 108 return _NCONT 109 } 110 if flags&_SigNotify != 0 { 111 if ignoredNote(note) { 112 return _NCONT 113 } 114 if sendNote(note) { 115 return _NCONT 116 } 117 } 118 if flags&_SigKill != 0 { 119 goto Exit 120 } 121 if flags&_SigThrow == 0 { 122 return _NCONT 123 } 124 Throw: 125 mp.throwing = throwTypeRuntime 126 mp.caughtsig.set(gp) 127 startpanic_m() 128 print(notestr, "\n") 129 print("PC=", hex(c.pc()), "\n") 130 print("\n") 131 level, _, docrash = gotraceback() 132 if level > 0 { 133 goroutineheader(gp) 134 tracebacktrap(c.pc(), c.sp(), c.lr(), gp) 135 tracebackothers(gp) 136 print("\n") 137 dumpregs(_ureg) 138 } 139 if docrash { 140 crash() 141 } 142 Exit: 143 goexitsall(note) 144 exits(note) 145 return _NDFLT // not reached 146 } 147 148 func sigenable(sig uint32) { 149 } 150 151 func sigdisable(sig uint32) { 152 } 153 154 func sigignore(sig uint32) { 155 } 156 157 func setProcessCPUProfiler(hz int32) { 158 } 159 160 func setThreadCPUProfiler(hz int32) { 161 // TODO: Enable profiling interrupts. 162 getg().m.profilehz = hz 163 } 164 165 // gsignalStack is unused on Plan 9. 166 type gsignalStack struct{}