]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: pass to signal handler value of g at time of signal
authorRuss Cox <rsc@golang.org>
Wed, 23 Feb 2011 19:47:42 +0000 (14:47 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 23 Feb 2011 19:47:42 +0000 (14:47 -0500)
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

14 files changed:
src/pkg/runtime/darwin/386/signal.c
src/pkg/runtime/darwin/386/sys.s
src/pkg/runtime/darwin/amd64/signal.c
src/pkg/runtime/darwin/amd64/sys.s
src/pkg/runtime/freebsd/386/signal.c
src/pkg/runtime/freebsd/386/sys.s
src/pkg/runtime/freebsd/amd64/signal.c
src/pkg/runtime/freebsd/amd64/sys.s
src/pkg/runtime/linux/386/signal.c
src/pkg/runtime/linux/386/sys.s
src/pkg/runtime/linux/amd64/signal.c
src/pkg/runtime/linux/amd64/sys.s
src/pkg/runtime/linux/arm/signal.c
src/pkg/runtime/linux/arm/sys.s

index 33f47d44f93bd6e7ea7fc327ece521929f33e05f..dd3050f0336edfb50d1df7a51ce5b59055a32099 100644 (file)
@@ -34,20 +34,19 @@ runtime·signame(int32 sig)
 }
 
 void
-runtime·sighandler(int32 sig, Siginfo *info, void *context)
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
        Ucontext *uc;
        Mcontext *mc;
        Regs *r;
        uintptr *sp;
-       G *gp;
        byte *pc;
 
        uc = context;
        mc = uc->uc_mcontext;
        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.
                // Look at instruction to see if it is a divide.
                // 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");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->eip, (void*)r->esp, 0, m->curg);
-               runtime·tracebackothers(m->curg);
+               runtime·traceback((void*)r->eip, (void*)r->esp, 0, gp);
+               runtime·tracebackothers(gp);
                runtime·dumpregs(r);
        }
 
index 7961e369c3a95cbd35ed69ee484a3c1c10370323..9d2caca0a1fde6278fa77112e2fb3bbf931df966 100644 (file)
@@ -80,33 +80,34 @@ TEXT runtime·sigtramp(SB),7,$40
        get_tls(CX)
 
        // save g
-       MOVL    g(CX), BP
-       MOVL    BP, 20(SP)
+       MOVL    g(CX), DI
+       MOVL    DI, 20(SP)
        
        // g = m->gsignal
        MOVL    m(CX), BP
        MOVL    m_gsignal(BP), BP
        MOVL    BP, g(CX)
 
-       MOVL    handler+0(FP), DI
-       // 4(FP) is sigstyle
-       MOVL    signo+8(FP), AX
-       MOVL    siginfo+12(FP), BX
-       MOVL    context+16(FP), CX
-
-       MOVL    AX, 0(SP)
+       // copy arguments to sighandler
+       MOVL    sig+8(FP), BX
+       MOVL    BX, 0(SP)
+       MOVL    info+12(FP), BX
        MOVL    BX, 4(SP)
-       MOVL    CX, 8(SP)
-       CALL    DI
+       MOVL    context+16(FP), BX
+       MOVL    BX, 8(SP)
+       MOVL    DI, 12(SP)
+       
+       MOVL    handler+0(FP), BX
+       CALL    BX
 
        // restore g
        get_tls(CX)
-       MOVL    20(SP), BP
-       MOVL    BP, g(CX)
+       MOVL    20(SP), DI
+       MOVL    DI, g(CX)
 
+       // call sigreturn
        MOVL    context+16(FP), CX
        MOVL    style+4(FP), BX
-
        MOVL    $0, 0(SP)       // "caller PC" - ignored
        MOVL    CX, 4(SP)
        MOVL    BX, 8(SP)
index 948b6c9c20a913cdc853c2e2f901b935344edb20..d12b12f3e6e2fe26301f97c563827580cc1e8172 100644 (file)
@@ -42,12 +42,11 @@ runtime·signame(int32 sig)
 }
 
 void
-runtime·sighandler(int32 sig, Siginfo *info, void *context)
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
        Ucontext *uc;
        Mcontext *mc;
        Regs *r;
-       G *gp;
        uintptr *sp;
        byte *pc;
 
@@ -55,7 +54,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context)
        mc = uc->uc_mcontext;
        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.
                // Look at instruction to see if it is a divide.
                // 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");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->rip, (void*)r->rsp, 0, g);
-               runtime·tracebackothers(g);
+               runtime·traceback((void*)r->rip, (void*)r->rsp, 0, gp);
+               runtime·tracebackothers(gp);
                runtime·dumpregs(r);
        }
 
index bc970156a3201d19d061e1e6cb2f9b6917f152b3..4f9e0d77a5bc30ba9e810ff63b068db279b47a42 100644 (file)
@@ -66,8 +66,8 @@ TEXT runtime·sigtramp(SB),7,$64
        get_tls(BX)
        
        // save g
-       MOVQ    g(BX), BP
-       MOVQ    BP, 40(SP)
+       MOVQ    g(BX), R10
+       MOVQ    R10, 48(SP)
        
        // g = m->gsignal
        MOVQ    m(BX), BP
@@ -77,18 +77,21 @@ TEXT runtime·sigtramp(SB),7,$64
        MOVL    DX, 0(SP)
        MOVQ    CX, 8(SP)
        MOVQ    R8, 16(SP)
-       MOVQ    R8, 24(SP)      // save ucontext
-       MOVQ    SI, 32(SP)      // save infostyle
+       MOVQ    R10, 24(SP)
+
+       MOVQ    R8, 32(SP)      // save ucontext
+       MOVQ    SI, 40(SP)      // save infostyle
        CALL    DI
 
        // restore g
        get_tls(BX)
-       MOVQ    40(SP), BP
-       MOVQ    BP, g(BX)
+       MOVQ    48(SP), R10
+       MOVQ    R10, g(BX)
 
+       // call sigreturn
        MOVL    $(0x2000000+184), AX    // sigreturn(ucontext, infostyle)
-       MOVQ    24(SP), DI      // saved ucontext
-       MOVQ    32(SP), SI      // saved infostyle
+       MOVQ    32(SP), DI      // saved ucontext
+       MOVQ    40(SP), SI      // saved infostyle
        SYSCALL
        INT $3  // not reached
 
index ddb11fc3bac2459020c7fd39e61ed8d41984f510..bf40c8bd02433ba91c66fad3375bb37d51c070db 100644 (file)
@@ -45,17 +45,16 @@ runtime·signame(int32 sig)
 }
 
 void
-runtime·sighandler(int32 sig, Siginfo* info, void* context)
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
        Ucontext *uc;
        Mcontext *r;
-       G *gp;
        uintptr *sp;
 
        uc = context;
        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.
                // Have to pass arguments out of band since
                // augmenting the stack frame would break
@@ -99,8 +98,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
        runtime·printf("\n");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->mc_eip, (void*)r->mc_esp, 0, m->curg);
-               runtime·tracebackothers(m->curg);
+               runtime·traceback((void*)r->mc_eip, (void*)r->mc_esp, 0, gp);
+               runtime·tracebackothers(gp);
                runtime·dumpregs(r);
        }
 
index 7110e6924e0daaa02d071e393cad03ca6f9b4543..60c189bf837c4999ba3725fe09b17277c7dd2f8d 100644 (file)
@@ -111,30 +111,36 @@ TEXT runtime·sigaction(SB),7,$-4
        CALL    runtime·notok(SB)
        RET
 
-TEXT runtime·sigtramp(SB),7,$40
-       // g = m->gsignal
-       get_tls(DX)
-       MOVL    m(DX), BP
-       MOVL    m_gsignal(BP), BP
-       MOVL    BP, g(DX)
+TEXT runtime·sigtramp(SB),7,$44
+       get_tls(CX)
 
-       MOVL    signo+0(FP), AX
-       MOVL    siginfo+4(FP), BX
-       MOVL    context+8(FP), CX
+       // save g
+       MOVL    g(CX), DI
+       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    CX, 8(SP)
-       CALL    runtime·sighandler(SB)
+       MOVL    context+8(FP), BX
+       MOVL    BX, 8(SP)
+       MOVL    DI, 12(SP)
 
-       // g = m->curg
-       get_tls(DX)
-       MOVL    m(DX), BP
-       MOVL    m_curg(BP), BP
-       MOVL    BP, g(DX)
+       CALL    runtime·sighandler(SB)
 
+       // restore g
+       get_tls(CX)
+       MOVL    20(SP), BX
+       MOVL    BX, g(CX)
+       
+       // call sigreturn
        MOVL    context+8(FP), AX
-
        MOVL    $0, 0(SP)       // syscall gap
        MOVL    AX, 4(SP)
        MOVL    $417, AX        // sigreturn(ucontext)
index 9f873d276b1fd3d09b2482277337765f0a96f71d..b2313fad32dc2c8917cfb7ed26436d0124e90fb9 100644 (file)
@@ -53,17 +53,16 @@ runtime·signame(int32 sig)
 }
 
 void
-runtime·sighandler(int32 sig, Siginfo* info, void* context)
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
        Ucontext *uc;
        Mcontext *r;
-       G *gp;
        uintptr *sp;
 
        uc = context;
        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.
                // Have to pass arguments out of band since
                // augmenting the stack frame would break
@@ -107,8 +106,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
        runtime·printf("\n");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->mc_rip, (void*)r->mc_rsp, 0, g);
-               runtime·tracebackothers(g);
+               runtime·traceback((void*)r->mc_rip, (void*)r->mc_rsp, 0, gp);
+               runtime·tracebackothers(gp);
                runtime·dumpregs(r);
        }
 
index b9cf3832dd55df6b2a0f94a907dbacf6a458b034..d986e9ac07e07adff30cd1538f824542100b94cd 100644 (file)
@@ -90,15 +90,29 @@ TEXT runtime·sigaction(SB),7,$-8
        CALL    runtime·notok(SB)
        RET
 
-TEXT runtime·sigtramp(SB),7,$24-16
-       get_tls(CX)
-       MOVQ    m(CX), AX
-       MOVQ    m_gsignal(AX), AX
-       MOVQ    AX, g(CX)
+TEXT runtime·sigtramp(SB),7,$64
+       get_tls(BX)
+       
+       // save g
+       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    SI, 8(SP)
        MOVQ    DX, 16(SP)
+       MOVQ    R10, 24(SP)
+       
        CALL    runtime·sighandler(SB)
+
+       // restore g
+       get_tls(BX)
+       MOVQ    40(SP), R10
+       MOVQ    R10, g(BX)
        RET
 
 TEXT runtime·mmap(SB),7,$0
index 9651a6f28012716bfcc1e74faeda2335edf519e3..7f20d058b85326b241e021942e29301b9a646ed5 100644 (file)
@@ -42,17 +42,16 @@ runtime·signame(int32 sig)
 }
 
 void
-runtime·sighandler(int32 sig, Siginfo* info, void* context)
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
        Ucontext *uc;
        Sigcontext *r;
        uintptr *sp;
-       G *gp;
 
        uc = context;
        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.
                // Have to pass arguments out of band since
                // augmenting the stack frame would break
@@ -96,8 +95,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
        runtime·printf("\n");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->eip, (void*)r->esp, 0, m->curg);
-               runtime·tracebackothers(m->curg);
+               runtime·traceback((void*)r->eip, (void*)r->esp, 0, gp);
+               runtime·tracebackothers(gp);
                runtime·dumpregs(r);
        }
 
index a1505b0b06f4ff4e1d77206e3f8bbaf8ff5ede0a..a684371beab5f6987b7fbbc9a793a383f632821d 100644 (file)
@@ -56,12 +56,12 @@ TEXT runtime·rt_sigaction(SB),7,$0
        INT     $0x80
        RET
 
-TEXT runtime·sigtramp(SB),7,$40
+TEXT runtime·sigtramp(SB),7,$44
        get_tls(CX)
        
        // save g
-       MOVL    g(CX), BX
-       MOVL    BX, 20(SP)
+       MOVL    g(CX), DI
+       MOVL    DI, 20(SP)
        
        // g = m->gsignal
        MOVL    m(CX), BX
@@ -75,6 +75,7 @@ TEXT runtime·sigtramp(SB),7,$40
        MOVL    BX, 4(SP)
        MOVL    context+8(FP), BX
        MOVL    BX, 8(SP)
+       MOVL    DI, 12(SP)
 
        CALL    runtime·sighandler(SB)
        
index 9e501c96d855c4fca040ef060d6cd31b86d36719..462f9a74d7afeaa10a3b287b54c23c7da4c14774 100644 (file)
@@ -50,19 +50,18 @@ runtime·signame(int32 sig)
 }
 
 void
-runtime·sighandler(int32 sig, Siginfo* info, void* context)
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
        Ucontext *uc;
        Mcontext *mc;
        Sigcontext *r;
        uintptr *sp;
-       G *gp;
 
        uc = context;
        mc = &uc->uc_mcontext;
        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.
                // Have to pass arguments out of band since
                // augmenting the stack frame would break
@@ -106,8 +105,8 @@ runtime·sighandler(int32 sig, Siginfo* info, void* context)
        runtime·printf("\n");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->rip, (void*)r->rsp, 0, g);
-               runtime·tracebackothers(g);
+               runtime·traceback((void*)r->rip, (void*)r->rsp, 0, gp);
+               runtime·tracebackothers(gp);
                runtime·dumpregs(r);
        }
 
index 170b659fc855668805b1a6d71aaed8df216308e3..1bf734dc06c1b6cf543b821bcec99d9d7c8263c3 100644 (file)
@@ -64,8 +64,8 @@ TEXT runtime·sigtramp(SB),7,$64
        get_tls(BX)
 
        // save g
-       MOVQ    g(BX), BP
-       MOVQ    BP, 40(SP)
+       MOVQ    g(BX), R10
+       MOVQ    R10, 40(SP)
 
        // g = m->gsignal
        MOVQ    m(BX), BP
@@ -75,12 +75,14 @@ TEXT runtime·sigtramp(SB),7,$64
        MOVQ    DI, 0(SP)
        MOVQ    SI, 8(SP)
        MOVQ    DX, 16(SP)
+       MOVQ    R10, 24(SP)
+
        CALL    runtime·sighandler(SB)
 
        // restore g
        get_tls(BX)
-       MOVQ    40(SP), BP
-       MOVQ    BP, g(BX)
+       MOVQ    40(SP), R10
+       MOVQ    R10, g(BX)
        RET
 
 TEXT runtime·sigignore(SB),7,$0
index 481bd13c620192483af65c7cbb9544f1576f0a71..843c40b683f30fad381bcc6b0bdb7e0b4c3d3a1a 100644 (file)
@@ -50,16 +50,15 @@ runtime·signame(int32 sig)
 }
 
 void
-runtime·sighandler(int32 sig, Siginfo *info, void *context)
+runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
 {
        Ucontext *uc;
        Sigcontext *r;
-       G *gp;
 
        uc = context;
        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.
                // Have to pass arguments out of band since
                // augmenting the stack frame would break
@@ -99,8 +98,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context)
        runtime·printf("\n");
 
        if(runtime·gotraceback()){
-               runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, m->curg);
-               runtime·tracebackothers(m->curg);
+               runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, gp);
+               runtime·tracebackothers(gp);
                runtime·printf("\n");
                runtime·dumpregs(r);
        }
index b25cf81aaac61bf633c1840bedf36a65a2af416f..6c222fc8aa00d1347ac013a2e50441b92924ce4c 100644 (file)
@@ -197,11 +197,24 @@ TEXT runtime·sigignore(SB),7,$0
        RET
 
 TEXT runtime·sigtramp(SB),7,$24
+       // save g
+       MOVW    g, R3
+       MOVW    g, 20(R13)
+       
+       // g = m->gsignal
        MOVW    m_gsignal(m), g
+
+       // copy arguments for call to sighandler
        MOVW    R0, 4(R13)
        MOVW    R1, 8(R13)
        MOVW    R2, 12(R13)
+       MOVW    R3, 16(R13)
+
        BL      runtime·sighandler(SB)
+       
+       // restore g
+       MOVW    20(R13), g
+
        RET
 
 TEXT runtime·rt_sigaction(SB),7,$0