Commit 690291a2 authored by Russ Cox's avatar Russ Cox

runtime: pass to signal handler value of g at time of signal

The existing code assumed that signals only arrived
while executing on the goroutine stack (g == m->curg),
not while executing on the scheduler stack (g == m->g0).

Most of the signal handling trampolines correctly saved
and restored g already, but the sighandler C code did not
have access to it.

Some rewriting of assembly to make the various
implementations as similar as possible.

Will need to change Windows too but I don't
understand how sigtramp gets called there.

R=r
CC=golang-dev
https://golang.org/cl/4203042
parent 4b376ef3
...@@ -34,20 +34,19 @@ runtime·signame(int32 sig) ...@@ -34,20 +34,19 @@ runtime·signame(int32 sig)
} }
void void
runtime·sighandler(int32 sig, Siginfo *info, void *context) runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{ {
Ucontext *uc; Ucontext *uc;
Mcontext *mc; Mcontext *mc;
Regs *r; Regs *r;
uintptr *sp; uintptr *sp;
G *gp;
byte *pc; byte *pc;
uc = context; uc = context;
mc = uc->uc_mcontext; mc = uc->uc_mcontext;
r = &mc->ss; r = &mc->ss;
if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Work around Leopard bug that doesn't set FPE_INTDIV. // Work around Leopard bug that doesn't set FPE_INTDIV.
// Look at instruction to see if it is a divide. // Look at instruction to see if it is a divide.
// Not necessary in Snow Leopard (si_code will be != 0). // Not necessary in Snow Leopard (si_code will be != 0).
...@@ -103,8 +102,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context) ...@@ -103,8 +102,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context)
runtime·printf("\n"); runtime·printf("\n");
if(runtime·gotraceback()){ if(runtime·gotraceback()){
runtime·traceback((void*)r->eip, (void*)r->esp, 0, m->curg); runtime·traceback((void*)r->eip, (void*)r->esp, 0, gp);
runtime·tracebackothers(m->curg); runtime·tracebackothers(gp);
runtime·dumpregs(r); runtime·dumpregs(r);
} }
......
...@@ -80,33 +80,34 @@ TEXT runtime·sigtramp(SB),7,$40 ...@@ -80,33 +80,34 @@ TEXT runtime·sigtramp(SB),7,$40
get_tls(CX) get_tls(CX)
// save g // save g
MOVL g(CX), BP MOVL g(CX), DI
MOVL BP, 20(SP) MOVL DI, 20(SP)
// g = m->gsignal // g = m->gsignal
MOVL m(CX), BP MOVL m(CX), BP
MOVL m_gsignal(BP), BP MOVL m_gsignal(BP), BP
MOVL BP, g(CX) MOVL BP, g(CX)
MOVL handler+0(FP), DI // copy arguments to sighandler
// 4(FP) is sigstyle MOVL sig+8(FP), BX
MOVL signo+8(FP), AX MOVL BX, 0(SP)
MOVL siginfo+12(FP), BX MOVL info+12(FP), BX
MOVL context+16(FP), CX
MOVL AX, 0(SP)
MOVL BX, 4(SP) MOVL BX, 4(SP)
MOVL CX, 8(SP) MOVL context+16(FP), BX
CALL DI MOVL BX, 8(SP)
MOVL DI, 12(SP)
MOVL handler+0(FP), BX
CALL BX
// restore g // restore g
get_tls(CX) get_tls(CX)
MOVL 20(SP), BP MOVL 20(SP), DI
MOVL BP, g(CX) MOVL DI, g(CX)
// call sigreturn
MOVL context+16(FP), CX MOVL context+16(FP), CX
MOVL style+4(FP), BX MOVL style+4(FP), BX
MOVL $0, 0(SP) // "caller PC" - ignored MOVL $0, 0(SP) // "caller PC" - ignored
MOVL CX, 4(SP) MOVL CX, 4(SP)
MOVL BX, 8(SP) MOVL BX, 8(SP)
......
...@@ -42,12 +42,11 @@ runtime·signame(int32 sig) ...@@ -42,12 +42,11 @@ runtime·signame(int32 sig)
} }
void void
runtime·sighandler(int32 sig, Siginfo *info, void *context) runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{ {
Ucontext *uc; Ucontext *uc;
Mcontext *mc; Mcontext *mc;
Regs *r; Regs *r;
G *gp;
uintptr *sp; uintptr *sp;
byte *pc; byte *pc;
...@@ -55,7 +54,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context) ...@@ -55,7 +54,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context)
mc = uc->uc_mcontext; mc = uc->uc_mcontext;
r = &mc->ss; r = &mc->ss;
if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Work around Leopard bug that doesn't set FPE_INTDIV. // Work around Leopard bug that doesn't set FPE_INTDIV.
// Look at instruction to see if it is a divide. // Look at instruction to see if it is a divide.
// Not necessary in Snow Leopard (si_code will be != 0). // Not necessary in Snow Leopard (si_code will be != 0).
...@@ -113,8 +112,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context) ...@@ -113,8 +112,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context)
runtime·printf("\n"); runtime·printf("\n");
if(runtime·gotraceback()){ if(runtime·gotraceback()){
runtime·traceback((void*)r->rip, (void*)r->rsp, 0, g); runtime·traceback((void*)r->rip, (void*)r->rsp, 0, gp);
runtime·tracebackothers(g); runtime·tracebackothers(gp);
runtime·dumpregs(r); runtime·dumpregs(r);
} }
......
...@@ -66,8 +66,8 @@ TEXT runtime·sigtramp(SB),7,$64 ...@@ -66,8 +66,8 @@ TEXT runtime·sigtramp(SB),7,$64
get_tls(BX) get_tls(BX)
// save g // save g
MOVQ g(BX), BP MOVQ g(BX), R10
MOVQ BP, 40(SP) MOVQ R10, 48(SP)
// g = m->gsignal // g = m->gsignal
MOVQ m(BX), BP MOVQ m(BX), BP
...@@ -77,18 +77,21 @@ TEXT runtime·sigtramp(SB),7,$64 ...@@ -77,18 +77,21 @@ TEXT runtime·sigtramp(SB),7,$64
MOVL DX, 0(SP) MOVL DX, 0(SP)
MOVQ CX, 8(SP) MOVQ CX, 8(SP)
MOVQ R8, 16(SP) MOVQ R8, 16(SP)
MOVQ R8, 24(SP) // save ucontext MOVQ R10, 24(SP)
MOVQ SI, 32(SP) // save infostyle
MOVQ R8, 32(SP) // save ucontext
MOVQ SI, 40(SP) // save infostyle
CALL DI CALL DI
// restore g // restore g
get_tls(BX) get_tls(BX)
MOVQ 40(SP), BP MOVQ 48(SP), R10
MOVQ BP, g(BX) MOVQ R10, g(BX)
// call sigreturn
MOVL $(0x2000000+184), AX // sigreturn(ucontext, infostyle) MOVL $(0x2000000+184), AX // sigreturn(ucontext, infostyle)
MOVQ 24(SP), DI // saved ucontext MOVQ 32(SP), DI // saved ucontext
MOVQ 32(SP), SI // saved infostyle MOVQ 40(SP), SI // saved infostyle
SYSCALL SYSCALL
INT $3 // not reached INT $3 // not reached
......
...@@ -45,17 +45,16 @@ runtime·signame(int32 sig) ...@@ -45,17 +45,16 @@ runtime·signame(int32 sig)
} }
void void
runtime·sighandler(int32 sig, Siginfo* info, void* context) runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{ {
Ucontext *uc; Ucontext *uc;
Mcontext *r; Mcontext *r;
G *gp;
uintptr *sp; uintptr *sp;
uc = context; uc = context;
r = &uc->uc_mcontext; r = &uc->uc_mcontext;
if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Make it look like a call to the signal func. // Make it look like a call to the signal func.
// Have to pass arguments out of band since // Have to pass arguments out of band since
// augmenting the stack frame would break // augmenting the stack frame would break
...@@ -99,8 +98,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context) ...@@ -99,8 +98,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
runtime·printf("\n"); runtime·printf("\n");
if(runtime·gotraceback()){ if(runtime·gotraceback()){
runtime·traceback((void*)r->mc_eip, (void*)r->mc_esp, 0, m->curg); runtime·traceback((void*)r->mc_eip, (void*)r->mc_esp, 0, gp);
runtime·tracebackothers(m->curg); runtime·tracebackothers(gp);
runtime·dumpregs(r); runtime·dumpregs(r);
} }
......
...@@ -111,30 +111,36 @@ TEXT runtime·sigaction(SB),7,$-4 ...@@ -111,30 +111,36 @@ TEXT runtime·sigaction(SB),7,$-4
CALL runtime·notok(SB) CALL runtime·notok(SB)
RET RET
TEXT runtime·sigtramp(SB),7,$40 TEXT runtime·sigtramp(SB),7,$44
// g = m->gsignal get_tls(CX)
get_tls(DX)
MOVL m(DX), BP
MOVL m_gsignal(BP), BP
MOVL BP, g(DX)
MOVL signo+0(FP), AX // save g
MOVL siginfo+4(FP), BX MOVL g(CX), DI
MOVL context+8(FP), CX MOVL DI, 20(SP)
// g = m->gsignal
MOVL m(CX), BX
MOVL m_gsignal(BX), BX
MOVL BX, g(CX)
MOVL AX, 0(SP) // copy arguments for call to sighandler
MOVL signo+0(FP), BX
MOVL BX, 0(SP)
MOVL info+4(FP), BX
MOVL BX, 4(SP) MOVL BX, 4(SP)
MOVL CX, 8(SP) MOVL context+8(FP), BX
CALL runtime·sighandler(SB) MOVL BX, 8(SP)
MOVL DI, 12(SP)
// g = m->curg CALL runtime·sighandler(SB)
get_tls(DX)
MOVL m(DX), BP
MOVL m_curg(BP), BP
MOVL BP, g(DX)
// restore g
get_tls(CX)
MOVL 20(SP), BX
MOVL BX, g(CX)
// call sigreturn
MOVL context+8(FP), AX MOVL context+8(FP), AX
MOVL $0, 0(SP) // syscall gap MOVL $0, 0(SP) // syscall gap
MOVL AX, 4(SP) MOVL AX, 4(SP)
MOVL $417, AX // sigreturn(ucontext) MOVL $417, AX // sigreturn(ucontext)
......
...@@ -53,17 +53,16 @@ runtime·signame(int32 sig) ...@@ -53,17 +53,16 @@ runtime·signame(int32 sig)
} }
void void
runtime·sighandler(int32 sig, Siginfo* info, void* context) runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{ {
Ucontext *uc; Ucontext *uc;
Mcontext *r; Mcontext *r;
G *gp;
uintptr *sp; uintptr *sp;
uc = context; uc = context;
r = &uc->uc_mcontext; r = &uc->uc_mcontext;
if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Make it look like a call to the signal func. // Make it look like a call to the signal func.
// Have to pass arguments out of band since // Have to pass arguments out of band since
// augmenting the stack frame would break // augmenting the stack frame would break
...@@ -107,8 +106,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context) ...@@ -107,8 +106,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
runtime·printf("\n"); runtime·printf("\n");
if(runtime·gotraceback()){ if(runtime·gotraceback()){
runtime·traceback((void*)r->mc_rip, (void*)r->mc_rsp, 0, g); runtime·traceback((void*)r->mc_rip, (void*)r->mc_rsp, 0, gp);
runtime·tracebackothers(g); runtime·tracebackothers(gp);
runtime·dumpregs(r); runtime·dumpregs(r);
} }
......
...@@ -90,15 +90,29 @@ TEXT runtime·sigaction(SB),7,$-8 ...@@ -90,15 +90,29 @@ TEXT runtime·sigaction(SB),7,$-8
CALL runtime·notok(SB) CALL runtime·notok(SB)
RET RET
TEXT runtime·sigtramp(SB),7,$24-16 TEXT runtime·sigtramp(SB),7,$64
get_tls(CX) get_tls(BX)
MOVQ m(CX), AX
MOVQ m_gsignal(AX), AX // save g
MOVQ AX, g(CX) MOVQ g(BX), R10
MOVQ R10, 40(SP)
// g = m->signal
MOVQ m(BX), BP
MOVQ m_gsignal(BP), BP
MOVQ BP, g(BX)
MOVQ DI, 0(SP) MOVQ DI, 0(SP)
MOVQ SI, 8(SP) MOVQ SI, 8(SP)
MOVQ DX, 16(SP) MOVQ DX, 16(SP)
MOVQ R10, 24(SP)
CALL runtime·sighandler(SB) CALL runtime·sighandler(SB)
// restore g
get_tls(BX)
MOVQ 40(SP), R10
MOVQ R10, g(BX)
RET RET
TEXT runtime·mmap(SB),7,$0 TEXT runtime·mmap(SB),7,$0
......
...@@ -42,17 +42,16 @@ runtime·signame(int32 sig) ...@@ -42,17 +42,16 @@ runtime·signame(int32 sig)
} }
void void
runtime·sighandler(int32 sig, Siginfo* info, void* context) runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{ {
Ucontext *uc; Ucontext *uc;
Sigcontext *r; Sigcontext *r;
uintptr *sp; uintptr *sp;
G *gp;
uc = context; uc = context;
r = &uc->uc_mcontext; r = &uc->uc_mcontext;
if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Make it look like a call to the signal func. // Make it look like a call to the signal func.
// Have to pass arguments out of band since // Have to pass arguments out of band since
// augmenting the stack frame would break // augmenting the stack frame would break
...@@ -96,8 +95,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context) ...@@ -96,8 +95,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
runtime·printf("\n"); runtime·printf("\n");
if(runtime·gotraceback()){ if(runtime·gotraceback()){
runtime·traceback((void*)r->eip, (void*)r->esp, 0, m->curg); runtime·traceback((void*)r->eip, (void*)r->esp, 0, gp);
runtime·tracebackothers(m->curg); runtime·tracebackothers(gp);
runtime·dumpregs(r); runtime·dumpregs(r);
} }
......
...@@ -56,12 +56,12 @@ TEXT runtime·rt_sigaction(SB),7,$0 ...@@ -56,12 +56,12 @@ TEXT runtime·rt_sigaction(SB),7,$0
INT $0x80 INT $0x80
RET RET
TEXT runtime·sigtramp(SB),7,$40 TEXT runtime·sigtramp(SB),7,$44
get_tls(CX) get_tls(CX)
// save g // save g
MOVL g(CX), BX MOVL g(CX), DI
MOVL BX, 20(SP) MOVL DI, 20(SP)
// g = m->gsignal // g = m->gsignal
MOVL m(CX), BX MOVL m(CX), BX
...@@ -75,6 +75,7 @@ TEXT runtime·sigtramp(SB),7,$40 ...@@ -75,6 +75,7 @@ TEXT runtime·sigtramp(SB),7,$40
MOVL BX, 4(SP) MOVL BX, 4(SP)
MOVL context+8(FP), BX MOVL context+8(FP), BX
MOVL BX, 8(SP) MOVL BX, 8(SP)
MOVL DI, 12(SP)
CALL runtime·sighandler(SB) CALL runtime·sighandler(SB)
......
...@@ -50,19 +50,18 @@ runtime·signame(int32 sig) ...@@ -50,19 +50,18 @@ runtime·signame(int32 sig)
} }
void void
runtime·sighandler(int32 sig, Siginfo* info, void* context) runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{ {
Ucontext *uc; Ucontext *uc;
Mcontext *mc; Mcontext *mc;
Sigcontext *r; Sigcontext *r;
uintptr *sp; uintptr *sp;
G *gp;
uc = context; uc = context;
mc = &uc->uc_mcontext; mc = &uc->uc_mcontext;
r = (Sigcontext*)mc; // same layout, more conveient names r = (Sigcontext*)mc; // same layout, more conveient names
if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Make it look like a call to the signal func. // Make it look like a call to the signal func.
// Have to pass arguments out of band since // Have to pass arguments out of band since
// augmenting the stack frame would break // augmenting the stack frame would break
...@@ -106,8 +105,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context) ...@@ -106,8 +105,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
runtime·printf("\n"); runtime·printf("\n");
if(runtime·gotraceback()){ if(runtime·gotraceback()){
runtime·traceback((void*)r->rip, (void*)r->rsp, 0, g); runtime·traceback((void*)r->rip, (void*)r->rsp, 0, gp);
runtime·tracebackothers(g); runtime·tracebackothers(gp);
runtime·dumpregs(r); runtime·dumpregs(r);
} }
......
...@@ -64,8 +64,8 @@ TEXT runtime·sigtramp(SB),7,$64 ...@@ -64,8 +64,8 @@ TEXT runtime·sigtramp(SB),7,$64
get_tls(BX) get_tls(BX)
// save g // save g
MOVQ g(BX), BP MOVQ g(BX), R10
MOVQ BP, 40(SP) MOVQ R10, 40(SP)
// g = m->gsignal // g = m->gsignal
MOVQ m(BX), BP MOVQ m(BX), BP
...@@ -75,12 +75,14 @@ TEXT runtime·sigtramp(SB),7,$64 ...@@ -75,12 +75,14 @@ TEXT runtime·sigtramp(SB),7,$64
MOVQ DI, 0(SP) MOVQ DI, 0(SP)
MOVQ SI, 8(SP) MOVQ SI, 8(SP)
MOVQ DX, 16(SP) MOVQ DX, 16(SP)
MOVQ R10, 24(SP)
CALL runtime·sighandler(SB) CALL runtime·sighandler(SB)
// restore g // restore g
get_tls(BX) get_tls(BX)
MOVQ 40(SP), BP MOVQ 40(SP), R10
MOVQ BP, g(BX) MOVQ R10, g(BX)
RET RET
TEXT runtime·sigignore(SB),7,$0 TEXT runtime·sigignore(SB),7,$0
......
...@@ -50,16 +50,15 @@ runtime·signame(int32 sig) ...@@ -50,16 +50,15 @@ runtime·signame(int32 sig)
} }
void void
runtime·sighandler(int32 sig, Siginfo *info, void *context) runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{ {
Ucontext *uc; Ucontext *uc;
Sigcontext *r; Sigcontext *r;
G *gp;
uc = context; uc = context;
r = &uc->uc_mcontext; r = &uc->uc_mcontext;
if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
// Make it look like a call to the signal func. // Make it look like a call to the signal func.
// Have to pass arguments out of band since // Have to pass arguments out of band since
// augmenting the stack frame would break // augmenting the stack frame would break
...@@ -99,8 +98,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context) ...@@ -99,8 +98,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context)
runtime·printf("\n"); runtime·printf("\n");
if(runtime·gotraceback()){ if(runtime·gotraceback()){
runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, m->curg); runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, gp);
runtime·tracebackothers(m->curg); runtime·tracebackothers(gp);
runtime·printf("\n"); runtime·printf("\n");
runtime·dumpregs(r); runtime·dumpregs(r);
} }
......
...@@ -197,11 +197,24 @@ TEXT runtime·sigignore(SB),7,$0 ...@@ -197,11 +197,24 @@ TEXT runtime·sigignore(SB),7,$0
RET RET
TEXT runtime·sigtramp(SB),7,$24 TEXT runtime·sigtramp(SB),7,$24
// save g
MOVW g, R3
MOVW g, 20(R13)
// g = m->gsignal
MOVW m_gsignal(m), g MOVW m_gsignal(m), g
// copy arguments for call to sighandler
MOVW R0, 4(R13) MOVW R0, 4(R13)
MOVW R1, 8(R13) MOVW R1, 8(R13)
MOVW R2, 12(R13) MOVW R2, 12(R13)
MOVW R3, 16(R13)
BL runtime·sighandler(SB) BL runtime·sighandler(SB)
// restore g
MOVW 20(R13), g
RET RET
TEXT runtime·rt_sigaction(SB),7,$0 TEXT runtime·rt_sigaction(SB),7,$0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment