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