From: Joel Sing Date: Tue, 15 May 2012 15:53:26 +0000 (+1000) Subject: runtime: fix netbsd signal handling X-Git-Tag: go1.1rc2~3205 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4a5a5b20a53493fc3c3803cb2099e38677a5d83f;p=gostls13.git runtime: fix netbsd signal handling Update/correct NetBSD signal handling - most of this is needed due to the correctly generated runtime definitions. R=golang-dev, m4dh4tt3r, rsc CC=golang-dev https://golang.org/cl/6195079 --- diff --git a/src/pkg/runtime/signal_netbsd_386.c b/src/pkg/runtime/signal_netbsd_386.c index b4871ee8e0..f5eb913b60 100644 --- a/src/pkg/runtime/signal_netbsd_386.c +++ b/src/pkg/runtime/signal_netbsd_386.c @@ -19,64 +19,66 @@ typedef struct sigaction { } Sigaction; void -runtime·dumpregs(Sigcontext *r) +runtime·dumpregs(McontextT *mc) { - runtime·printf("eax %x\n", r->sc_eax); - runtime·printf("ebx %x\n", r->sc_ebx); - runtime·printf("ecx %x\n", r->sc_ecx); - runtime·printf("edx %x\n", r->sc_edx); - runtime·printf("edi %x\n", r->sc_edi); - runtime·printf("esi %x\n", r->sc_esi); - runtime·printf("ebp %x\n", r->sc_ebp); - runtime·printf("esp %x\n", r->sc_esp); - runtime·printf("eip %x\n", r->sc_eip); - runtime·printf("eflags %x\n", r->sc_eflags); - runtime·printf("cs %x\n", r->sc_cs); - runtime·printf("fs %x\n", r->sc_fs); - runtime·printf("gs %x\n", r->sc_gs); + runtime·printf("eax %x\n", mc->__gregs[REG_EAX]); + runtime·printf("ebx %x\n", mc->__gregs[REG_EBX]); + runtime·printf("ecx %x\n", mc->__gregs[REG_ECX]); + runtime·printf("edx %x\n", mc->__gregs[REG_EDX]); + runtime·printf("edi %x\n", mc->__gregs[REG_EDI]); + runtime·printf("esi %x\n", mc->__gregs[REG_ESI]); + runtime·printf("ebp %x\n", mc->__gregs[REG_EBP]); + runtime·printf("esp %x\n", mc->__gregs[REG_ESP]); + runtime·printf("eip %x\n", mc->__gregs[REG_EIP]); + runtime·printf("eflags %x\n", mc->__gregs[REG_EFL]); + runtime·printf("cs %x\n", mc->__gregs[REG_CS]); + runtime·printf("fs %x\n", mc->__gregs[REG_FS]); + runtime·printf("gs %x\n", mc->__gregs[REG_GS]); } void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) { - Sigcontext *r = context; + UcontextT *uc = context; + McontextT *mc = &uc->uc_mcontext; uintptr *sp; SigTab *t; if(sig == SIGPROF) { - runtime·sigprof((uint8*)r->sc_eip, (uint8*)r->sc_esp, nil, gp); + runtime·sigprof((uint8*)mc->__gregs[REG_EIP], + (uint8*)mc->__gregs[REG_ESP], nil, gp); return; } t = &runtime·sigtab[sig]; - if(info->si_code != SI_USER && (t->flags & SigPanic)) { + if(info->_code != SI_USER && (t->flags & SigPanic)) { if(gp == nil) goto Throw; // Make it look like a call to the signal func. - // Have to pass arguments out of band since + // We need to pass arguments out of band since // augmenting the stack frame would break // the unwinding code. gp->sig = sig; - gp->sigcode0 = info->si_code; - gp->sigcode1 = *(uintptr*)((byte*)info + 12); /* si_addr */ - gp->sigpc = r->sc_eip; - - // Only push runtime·sigpanic if r->sc_eip != 0. - // If r->sc_eip == 0, probably panicked because of a - // call to a nil func. Not pushing that onto sp will - // make the trace look like a call to runtime·sigpanic instead. - // (Otherwise the trace will end at runtime·sigpanic and we - // won't get to see who faulted.) - if(r->sc_eip != 0) { - sp = (uintptr*)r->sc_esp; - *--sp = r->sc_eip; - r->sc_esp = (uintptr)sp; + gp->sigcode0 = info->_code; + gp->sigcode1 = *(uintptr*)&info->_reason[0]; /* _addr */ + gp->sigpc = mc->__gregs[REG_EIP]; + + // Only push runtime·sigpanic if __gregs[REG_EIP] != 0. + // If __gregs[REG_EIP] == 0, probably panicked because of a + // call to a nil func. Not pushing that onto sp will make the + // trace look like a call to runtime·sigpanic instead. + // (Otherwise the trace will end at runtime·sigpanic + // and we won't get to see who faulted.) + if(mc->__gregs[REG_EIP] != 0) { + sp = (uintptr*)mc->__gregs[REG_ESP]; + *--sp = mc->__gregs[REG_EIP]; + mc->__gregs[REG_ESP] = (uintptr)sp; } - r->sc_eip = (uintptr)runtime·sigpanic; + mc->__gregs[REG_EIP] = (uintptr)runtime·sigpanic; return; } - if(info->si_code == SI_USER || (t->flags & SigNotify)) + if(info->_code == SI_USER || (t->flags & SigNotify)) if(runtime·sigsend(sig)) return; if(t->flags & SigKill) @@ -92,13 +94,14 @@ Throw: else runtime·printf("%s\n", runtime·sigtab[sig].name); - runtime·printf("PC=%X\n", r->sc_eip); + runtime·printf("PC=%X\n", mc->__gregs[REG_EIP]); runtime·printf("\n"); if(runtime·gotraceback()){ - runtime·traceback((void*)r->sc_eip, (void*)r->sc_esp, 0, gp); + runtime·traceback((void*)mc->__gregs[REG_EIP], + (void*)mc->__gregs[REG_ESP], 0, gp); runtime·tracebackothers(gp); - runtime·dumpregs(r); + runtime·dumpregs(mc); } runtime·exit(2); @@ -109,7 +112,7 @@ runtime·signalstack(byte *p, int32 n) { Sigaltstack st; - st.ss_sp = (int8*)p; + st.ss_sp = p; st.ss_size = n; st.ss_flags = 0; runtime·sigaltstack(&st, nil); diff --git a/src/pkg/runtime/signal_netbsd_amd64.c b/src/pkg/runtime/signal_netbsd_amd64.c index a27f9db24d..f8172c31f0 100644 --- a/src/pkg/runtime/signal_netbsd_amd64.c +++ b/src/pkg/runtime/signal_netbsd_amd64.c @@ -19,73 +19,73 @@ typedef struct sigaction { } Sigaction; void -runtime·dumpregs(Sigcontext *r) +runtime·dumpregs(McontextT *mc) { - runtime·printf("rax %X\n", r->sc_rax); - runtime·printf("rbx %X\n", r->sc_rbx); - runtime·printf("rcx %X\n", r->sc_rcx); - runtime·printf("rdx %X\n", r->sc_rdx); - runtime·printf("rdi %X\n", r->sc_rdi); - runtime·printf("rsi %X\n", r->sc_rsi); - runtime·printf("rbp %X\n", r->sc_rbp); - runtime·printf("rsp %X\n", r->sc_rsp); - runtime·printf("r8 %X\n", r->sc_r8); - runtime·printf("r9 %X\n", r->sc_r9); - runtime·printf("r10 %X\n", r->sc_r10); - runtime·printf("r11 %X\n", r->sc_r11); - runtime·printf("r12 %X\n", r->sc_r12); - runtime·printf("r13 %X\n", r->sc_r13); - runtime·printf("r14 %X\n", r->sc_r14); - runtime·printf("r15 %X\n", r->sc_r15); - runtime·printf("rip %X\n", r->sc_rip); - runtime·printf("rflags %X\n", r->sc_rflags); - runtime·printf("cs %X\n", r->sc_cs); - runtime·printf("fs %X\n", r->sc_fs); - runtime·printf("gs %X\n", r->sc_gs); + runtime·printf("rax %X\n", mc->__gregs[REG_RAX]); + runtime·printf("rbx %X\n", mc->__gregs[REG_RBX]); + runtime·printf("rcx %X\n", mc->__gregs[REG_RCX]); + runtime·printf("rdx %X\n", mc->__gregs[REG_RDX]); + runtime·printf("rdi %X\n", mc->__gregs[REG_RDI]); + runtime·printf("rsi %X\n", mc->__gregs[REG_RSI]); + runtime·printf("rbp %X\n", mc->__gregs[REG_RBP]); + runtime·printf("rsp %X\n", mc->__gregs[REG_RSP]); + runtime·printf("r8 %X\n", mc->__gregs[REG_R8]); + runtime·printf("r9 %X\n", mc->__gregs[REG_R9]); + runtime·printf("r10 %X\n", mc->__gregs[REG_R10]); + runtime·printf("r11 %X\n", mc->__gregs[REG_R11]); + runtime·printf("r12 %X\n", mc->__gregs[REG_R12]); + runtime·printf("r13 %X\n", mc->__gregs[REG_R13]); + runtime·printf("r14 %X\n", mc->__gregs[REG_R14]); + runtime·printf("r15 %X\n", mc->__gregs[REG_R15]); + runtime·printf("rip %X\n", mc->__gregs[REG_RIP]); + runtime·printf("rflags %X\n", mc->__gregs[REG_RFLAGS]); + runtime·printf("cs %X\n", mc->__gregs[REG_CS]); + runtime·printf("fs %X\n", mc->__gregs[REG_FS]); + runtime·printf("gs %X\n", mc->__gregs[REG_GS]); } void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) { - Sigcontext *r = context; + UcontextT *uc = context; + McontextT *mc = &uc->uc_mcontext; uintptr *sp; SigTab *t; if(sig == SIGPROF) { - runtime·sigprof((uint8*)r->sc_rip, - (uint8*)r->sc_rsp, nil, gp); + runtime·sigprof((uint8*)mc->__gregs[REG_RIP], + (uint8*)mc->__gregs[REG_RSP], nil, gp); return; } t = &runtime·sigtab[sig]; - if(info->si_code != SI_USER && (t->flags & SigPanic)) { + if(info->_code != SI_USER && (t->flags & SigPanic)) { if(gp == nil) goto Throw; // Make it look like a call to the signal func. - // Have to pass arguments out of band since - // augmenting the stack frame would break - // the unwinding code. + // We need to pass arguments out of band since augmenting the + // stack frame would break the unwinding code. gp->sig = sig; - gp->sigcode0 = info->si_code; - gp->sigcode1 = *(uintptr*)((byte*)info + 16); /* si_addr */ - gp->sigpc = r->sc_rip; - - // Only push runtime·sigpanic if r->mc_rip != 0. - // If r->mc_rip == 0, probably panicked because of a - // call to a nil func. Not pushing that onto sp will - // make the trace look like a call to runtime·sigpanic instead. - // (Otherwise the trace will end at runtime·sigpanic and we - // won't get to see who faulted.) - if(r->sc_rip != 0) { - sp = (uintptr*)r->sc_rsp; - *--sp = r->sc_rip; - r->sc_rsp = (uintptr)sp; + gp->sigcode0 = info->_code; + gp->sigcode1 = *(uintptr*)&info->_reason[0]; /* _addr */ + gp->sigpc = mc->__gregs[REG_RIP]; + + // Only push runtime·sigpanic if __gregs[REG_RIP] != 0. + // If __gregs[REG_RIP] == 0, probably panicked because of a + // call to a nil func. Not pushing that onto sp will make the + // trace look like a call to runtime·sigpanic instead. + // (Otherwise the trace will end at runtime·sigpanic + // and we won't get to see who faulted.) + if(mc->__gregs[REG_RIP] != 0) { + sp = (uintptr*)mc->__gregs[REG_RSP]; + *--sp = mc->__gregs[REG_RIP]; + mc->__gregs[REG_RSP] = (uintptr)sp; } - r->sc_rip = (uintptr)runtime·sigpanic; + mc->__gregs[REG_RIP] = (uintptr)runtime·sigpanic; return; } - if(info->si_code == SI_USER || (t->flags & SigNotify)) + if(info->_code == SI_USER || (t->flags & SigNotify)) if(runtime·sigsend(sig)) return; if(t->flags & SigKill) @@ -101,13 +101,14 @@ Throw: else runtime·printf("%s\n", runtime·sigtab[sig].name); - runtime·printf("PC=%X\n", r->sc_rip); + runtime·printf("PC=%X\n", mc->__gregs[REG_RIP]); runtime·printf("\n"); if(runtime·gotraceback()){ - runtime·traceback((void*)r->sc_rip, (void*)r->sc_rsp, 0, gp); + runtime·traceback((void*)mc->__gregs[REG_RIP], + (void*)mc->__gregs[REG_RSP], 0, gp); runtime·tracebackothers(gp); - runtime·dumpregs(r); + runtime·dumpregs(mc); } runtime·exit(2); @@ -118,7 +119,7 @@ runtime·signalstack(byte *p, int32 n) { Sigaltstack st; - st.ss_sp = (int8*)p; + st.ss_sp = p; st.ss_size = n; st.ss_flags = 0; runtime·sigaltstack(&st, nil); diff --git a/src/pkg/runtime/signals_netbsd.h b/src/pkg/runtime/signals_netbsd.h index 4d27e050d0..7140de86fc 100644 --- a/src/pkg/runtime/signals_netbsd.h +++ b/src/pkg/runtime/signals_netbsd.h @@ -9,16 +9,16 @@ #define D SigDefault SigTab runtime·sigtab[] = { - /* 0 */ 0, "SIGNONE: no trap", - /* 1 */ N+K, "SIGHUP: terminal line hangup", - /* 2 */ N+K, "SIGINT: interrupt", - /* 3 */ N+T, "SIGQUIT: quit", - /* 4 */ T, "SIGILL: illegal instruction", - /* 5 */ T, "SIGTRAP: trace trap", - /* 6 */ N+T, "SIGABRT: abort", - /* 7 */ T, "SIGEMT: emulate instruction executed", - /* 8 */ P, "SIGFPE: floating-point exception", - /* 9 */ 0, "SIGKILL: kill", + /* 0 */ 0, "SIGNONE: no trap", + /* 1 */ N+K, "SIGHUP: terminal line hangup", + /* 2 */ N+K, "SIGINT: interrupt", + /* 3 */ N+T, "SIGQUIT: quit", + /* 4 */ T, "SIGILL: illegal instruction", + /* 5 */ T, "SIGTRAP: trace trap", + /* 6 */ N+T, "SIGABRT: abort", + /* 7 */ T, "SIGEMT: emulate instruction executed", + /* 8 */ P, "SIGFPE: floating-point exception", + /* 9 */ 0, "SIGKILL: kill", /* 10 */ P, "SIGBUS: bus error", /* 11 */ P, "SIGSEGV: segmentation violation", /* 12 */ T, "SIGSYS: bad system call",