github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/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 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 if(gp != m->g0 && gp != m->gsignal) 51 runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp); 52 return; 53 } 54 55 t = &runtime·sigtab[sig]; 56 if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) { 57 if(gp == nil || gp == m->g0) 58 goto Throw; 59 60 // Make it look like a call to the signal func. 61 // Have to pass arguments out of band since 62 // augmenting the stack frame would break 63 // the unwinding code. 64 gp->sig = sig; 65 gp->sigcode0 = SIG_CODE0(info, ctxt); 66 gp->sigcode1 = SIG_CODE1(info, ctxt); 67 gp->sigpc = SIG_RIP(info, ctxt); 68 69 #ifdef GOOS_darwin 70 // Work around Leopard bug that doesn't set FPE_INTDIV. 71 // Look at instruction to see if it is a divide. 72 // Not necessary in Snow Leopard (si_code will be != 0). 73 if(sig == SIGFPE && gp->sigcode0 == 0) { 74 byte *pc; 75 pc = (byte*)gp->sigpc; 76 if((pc[0]&0xF0) == 0x40) // 64-bit REX prefix 77 pc++; 78 else if(pc[0] == 0x66) // 16-bit instruction prefix 79 pc++; 80 if(pc[0] == 0xF6 || pc[0] == 0xF7) 81 gp->sigcode0 = FPE_INTDIV; 82 } 83 #endif 84 85 // Only push runtime·sigpanic if rip != 0. 86 // If rip == 0, probably panicked because of a 87 // call to a nil func. Not pushing that onto sp will 88 // make the trace look like a call to runtime·sigpanic instead. 89 // (Otherwise the trace will end at runtime·sigpanic and we 90 // won't get to see who faulted.) 91 if(SIG_RIP(info, ctxt) != 0) { 92 sp = (uintptr*)SIG_RSP(info, ctxt); 93 *--sp = SIG_RIP(info, ctxt); 94 SIG_RSP(info, ctxt) = (uintptr)sp; 95 } 96 SIG_RIP(info, ctxt) = (uintptr)runtime·sigpanic; 97 return; 98 } 99 100 if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify)) 101 if(runtime·sigsend(sig)) 102 return; 103 if(t->flags & SigKill) 104 runtime·exit(2); 105 if(!(t->flags & SigThrow)) 106 return; 107 108 Throw: 109 runtime·startpanic(); 110 111 if(sig < 0 || sig >= NSIG) 112 runtime·printf("Signal %d\n", sig); 113 else 114 runtime·printf("%s\n", runtime·sigtab[sig].name); 115 116 runtime·printf("PC=%X\n", SIG_RIP(info, ctxt)); 117 if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { 118 runtime·printf("signal arrived during cgo execution\n"); 119 gp = m->lockedg; 120 } 121 runtime·printf("\n"); 122 123 if(runtime·gotraceback(&crash)){ 124 runtime·traceback((void*)SIG_RIP(info, ctxt), (void*)SIG_RSP(info, ctxt), 0, gp); 125 runtime·tracebackothers(gp); 126 runtime·dumpregs(info, ctxt); 127 } 128 129 if(crash) 130 runtime·crash(); 131 132 runtime·exit(2); 133 }