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