github.com/reiver/go@v0.0.0-20150109200633-1d0c7792f172/src/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 "unsafe" 8 9 func sighandler(_ureg *ureg, note *byte, gp *g) int { 10 _g_ := getg() 11 var t sigTabT 12 var docrash bool 13 var length int 14 var sig int 15 var flags int 16 17 c := &sigctxt{_ureg} 18 19 // The kernel will never pass us a nil note or ureg so we probably 20 // made a mistake somewhere in sigtramp. 21 if _ureg == nil || note == nil { 22 print("sighandler: ureg ", _ureg, " note ", note, "\n") 23 goto Throw 24 } 25 // Check that the note is no more than ERRMAX bytes (including 26 // the trailing NUL). We should never receive a longer note. 27 length = findnull(note) 28 if length > _ERRMAX-1 { 29 print("sighandler: note is longer than ERRMAX\n") 30 goto Throw 31 } 32 // See if the note matches one of the patterns in sigtab. 33 // Notes that do not match any pattern can be handled at a higher 34 // level by the program but will otherwise be ignored. 35 flags = _SigNotify 36 for sig, t = range sigtable { 37 n := len(t.name) 38 if length < n { 39 continue 40 } 41 if strncmp(note, &t.name[0], uintptr(n)) == 0 { 42 flags = t.flags 43 break 44 } 45 } 46 if flags&_SigGoExit != 0 { 47 exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix. 48 } 49 if flags&_SigPanic != 0 { 50 // Copy the error string from sigtramp's stack into m->notesig so 51 // we can reliably access it from the panic routines. 52 memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(length+1)) 53 gp.sig = uint32(sig) 54 gp.sigpc = c.pc() 55 // Only push sigpanic if PC != 0. 56 // 57 // If PC == 0, probably panicked because of a call to a nil func. 58 // Not pushing that onto SP will make the trace look like a call 59 // to sigpanic instead. (Otherwise the trace will end at 60 // sigpanic and we won't get to see who faulted). 61 if c.pc() != 0 { 62 sp := c.sp() 63 if regSize > ptrSize { 64 sp -= ptrSize 65 *(*uintptr)(unsafe.Pointer(sp)) = 0 66 } 67 sp -= ptrSize 68 *(*uintptr)(unsafe.Pointer(sp)) = c.pc() 69 c.setsp(sp) 70 } 71 c.setpc(funcPC(sigpanic)) 72 return _NCONT 73 } 74 if flags&_SigNotify != 0 { 75 // TODO(ality): See if os/signal wants it. 76 //if(sigsend(...)) 77 // return _NCONT; 78 } 79 if flags&_SigKill != 0 { 80 goto Exit 81 } 82 if flags&_SigThrow == 0 { 83 return _NCONT 84 } 85 Throw: 86 _g_.m.throwing = 1 87 _g_.m.caughtsig = gp 88 startpanic() 89 print(gostringnocopy(note), "\n") 90 print("PC=", hex(c.pc()), "\n") 91 print("\n") 92 if gotraceback(&docrash) > 0 { 93 goroutineheader(gp) 94 tracebacktrap(c.pc(), c.sp(), 0, gp) 95 tracebackothers(gp) 96 print("\n") 97 dumpregs(_ureg) 98 } 99 if docrash { 100 crash() 101 } 102 Exit: 103 goexitsall(note) 104 exits(note) 105 return _NDFLT // not reached 106 } 107 108 func sigenable(sig uint32) { 109 } 110 111 func sigdisable(sig uint32) { 112 } 113 114 func resetcpuprofiler(hz int32) { 115 // TODO: Enable profiling interrupts. 116 getg().m.profilehz = hz 117 }