github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/signal_amd64.c (about) 1 // Copyright 2013 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 // +build darwin dragonfly freebsd linux netbsd openbsd 6 7 #include "runtime.h" 8 #include "defs_GOOS_GOARCH.h" 9 #include "os_GOOS.h" 10 #include "signal_GOOS_GOARCH.h" 11 #include "signals_GOOS.h" 12 13 void 14 runtime·dumpregs(Siginfo *info, void *ctxt) 15 { 16 USED(info); 17 USED(ctxt); 18 19 runtime·printf("rax %X\n", SIG_RAX(info, ctxt)); 20 runtime·printf("rbx %X\n", SIG_RBX(info, ctxt)); 21 runtime·printf("rcx %X\n", SIG_RCX(info, ctxt)); 22 runtime·printf("rdx %X\n", SIG_RDX(info, ctxt)); 23 runtime·printf("rdi %X\n", SIG_RDI(info, ctxt)); 24 runtime·printf("rsi %X\n", SIG_RSI(info, ctxt)); 25 runtime·printf("rbp %X\n", SIG_RBP(info, ctxt)); 26 runtime·printf("rsp %X\n", SIG_RSP(info, ctxt)); 27 runtime·printf("r8 %X\n", SIG_R8(info, ctxt) ); 28 runtime·printf("r9 %X\n", SIG_R9(info, ctxt) ); 29 runtime·printf("r10 %X\n", SIG_R10(info, ctxt)); 30 runtime·printf("r11 %X\n", SIG_R11(info, ctxt)); 31 runtime·printf("r12 %X\n", SIG_R12(info, ctxt)); 32 runtime·printf("r13 %X\n", SIG_R13(info, ctxt)); 33 runtime·printf("r14 %X\n", SIG_R14(info, ctxt)); 34 runtime·printf("r15 %X\n", SIG_R15(info, ctxt)); 35 runtime·printf("rip %X\n", SIG_RIP(info, ctxt)); 36 runtime·printf("rflags %X\n", SIG_RFLAGS(info, ctxt)); 37 runtime·printf("cs %X\n", SIG_CS(info, ctxt)); 38 runtime·printf("fs %X\n", SIG_FS(info, ctxt)); 39 runtime·printf("gs %X\n", SIG_GS(info, ctxt)); 40 } 41 42 void 43 runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) 44 { 45 uintptr *sp; 46 SigTab *t; 47 bool crash; 48 49 if(sig == SIGPROF) { 50 runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp); 51 return; 52 } 53 54 t = &runtime·sigtab[sig]; 55 if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) { 56 if(gp == nil || gp == m->g0) 57 goto Throw; 58 59 // Make it look like a call to the signal func. 60 // Have to pass arguments out of band since 61 // augmenting the stack frame would break 62 // the unwinding code. 63 gp->sig = sig; 64 gp->sigcode0 = SIG_CODE0(info, ctxt); 65 gp->sigcode1 = SIG_CODE1(info, ctxt); 66 gp->sigpc = SIG_RIP(info, ctxt); 67 68 #ifdef GOOS_darwin 69 // Work around Leopard bug that doesn't set FPE_INTDIV. 70 // Look at instruction to see if it is a divide. 71 // Not necessary in Snow Leopard (si_code will be != 0). 72 if(sig == SIGFPE && gp->sigcode0 == 0) { 73 byte *pc; 74 pc = (byte*)gp->sigpc; 75 if((pc[0]&0xF0) == 0x40) // 64-bit REX prefix 76 pc++; 77 else if(pc[0] == 0x66) // 16-bit instruction prefix 78 pc++; 79 if(pc[0] == 0xF6 || pc[0] == 0xF7) 80 gp->sigcode0 = FPE_INTDIV; 81 } 82 #endif 83 84 // Only push runtime·sigpanic if rip != 0. 85 // If rip == 0, probably panicked because of a 86 // call to a nil func. Not pushing that onto sp will 87 // make the trace look like a call to runtime·sigpanic instead. 88 // (Otherwise the trace will end at runtime·sigpanic and we 89 // won't get to see who faulted.) 90 if(SIG_RIP(info, ctxt) != 0) { 91 sp = (uintptr*)SIG_RSP(info, ctxt); 92 *--sp = SIG_RIP(info, ctxt); 93 SIG_RSP(info, ctxt) = (uintptr)sp; 94 } 95 SIG_RIP(info, ctxt) = (uintptr)runtime·sigpanic; 96 return; 97 } 98 99 if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify)) 100 if(runtime·sigsend(sig)) 101 return; 102 if(t->flags & SigKill) 103 runtime·exit(2); 104 if(!(t->flags & SigThrow)) 105 return; 106 107 Throw: 108 m->throwing = 1; 109 m->caughtsig = gp; 110 runtime·startpanic(); 111 112 if(sig < 0 || sig >= NSIG) 113 runtime·printf("Signal %d\n", sig); 114 else 115 runtime·printf("%s\n", runtime·sigtab[sig].name); 116 117 runtime·printf("PC=%X\n", SIG_RIP(info, ctxt)); 118 if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { 119 runtime·printf("signal arrived during cgo execution\n"); 120 gp = m->lockedg; 121 } 122 runtime·printf("\n"); 123 124 if(runtime·gotraceback(&crash)){ 125 runtime·traceback(SIG_RIP(info, ctxt), SIG_RSP(info, ctxt), 0, gp); 126 runtime·tracebackothers(gp); 127 runtime·printf("\n"); 128 runtime·dumpregs(info, ctxt); 129 } 130 131 if(crash) 132 runtime·crash(); 133 134 runtime·exit(2); 135 }