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.
13 // May run during STW, so write barriers are not allowed.
15 //go:nowritebarrierrec
16 func sighandler(_ureg *ureg, note *byte, gp *g) int {
27 notestr := gostringnocopy(note)
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")
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")
41 if isAbortPC(c.pc()) {
42 // Never turn abort into a panic.
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.
49 for sig, t = range sigtable {
50 if hasPrefix(notestr, t.name) {
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
60 if flags&_SigGoExit != 0 {
61 exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
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))
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() {
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
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).
99 *(*uintptr)(unsafe.Pointer(sp)) = pc
104 c.setpc(abi.FuncPCABI0(sigpanictramp))
106 c.setpc(abi.FuncPCABI0(sigpanic0))
110 if flags&_SigNotify != 0 {
111 if ignoredNote(note) {
118 if flags&_SigKill != 0 {
121 if flags&_SigThrow == 0 {
125 mp.throwing = throwTypeRuntime
129 print("PC=", hex(c.pc()), "\n")
131 level, _, docrash = gotraceback()
134 tracebacktrap(c.pc(), c.sp(), c.lr(), gp)
145 return _NDFLT // not reached
148 func sigenable(sig uint32) {
151 func sigdisable(sig uint32) {
154 func sigignore(sig uint32) {
157 func setProcessCPUProfiler(hz int32) {
160 func setThreadCPUProfiler(hz int32) {
161 // TODO: Enable profiling interrupts.
162 getg().m.profilehz = hz
165 // gsignalStack is unused on Plan 9.
166 type gsignalStack struct{}