1
0
mirror of https://github.com/golang/go synced 2024-11-20 06:54:42 -07:00

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
This commit is contained in:
Russ Cox 2011-02-23 14:47:42 -05:00
parent 4b376ef328
commit 690291a2c0
14 changed files with 120 additions and 87 deletions

View File

@ -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)
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);
} }

View File

@ -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)

View File

@ -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)
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)
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);
} }

View File

@ -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
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

View File

@ -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)
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);
} }

View File

@ -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
get_tls(CX)
// save g
MOVL g(CX), DI
MOVL DI, 20(SP)
// g = m->gsignal // g = m->gsignal
get_tls(DX) MOVL m(CX), BX
MOVL m(DX), BP MOVL m_gsignal(BX), BX
MOVL m_gsignal(BP), BP MOVL BX, g(CX)
MOVL BP, g(DX)
MOVL signo+0(FP), AX // copy arguments for call to sighandler
MOVL siginfo+4(FP), BX MOVL signo+0(FP), BX
MOVL context+8(FP), CX MOVL BX, 0(SP)
MOVL info+4(FP), BX
MOVL AX, 0(SP)
MOVL BX, 4(SP) MOVL BX, 4(SP)
MOVL CX, 8(SP) MOVL context+8(FP), BX
MOVL BX, 8(SP)
MOVL DI, 12(SP)
CALL runtime·sighandler(SB) CALL runtime·sighandler(SB)
// g = m->curg // restore g
get_tls(DX) get_tls(CX)
MOVL m(DX), BP MOVL 20(SP), BX
MOVL m_curg(BP), BP MOVL BX, g(CX)
MOVL BP, g(DX)
// 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)

View File

@ -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)
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);
} }

View File

@ -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

View File

@ -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)
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);
} }

View File

@ -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
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)

View File

@ -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)
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);
} }

View File

@ -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
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

View File

@ -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)
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);
} }

View File

@ -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