]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: block signals during thread creation on openbsd
authorJoel Sing <jsing@google.com>
Tue, 10 Apr 2012 11:57:05 +0000 (21:57 +1000)
committerJoel Sing <jsing@google.com>
Tue, 10 Apr 2012 11:57:05 +0000 (21:57 +1000)
Block signals during thread creation, otherwise the new thread can
receive a signal prior to initialisation completing.

Fixes #3102.

R=golang-dev, rsc, devon.odell, minux.ma
CC=golang-dev
https://golang.org/cl/5757064

src/pkg/runtime/os_openbsd.h
src/pkg/runtime/signal_openbsd_amd64.c
src/pkg/runtime/signals_openbsd.h
src/pkg/runtime/sys_openbsd_386.s
src/pkg/runtime/sys_openbsd_amd64.s
src/pkg/runtime/thread_openbsd.c

index 4ecf78d882f21598b600254252522baa59c6b784..b2d79e7f998fafe5522ea1b2adc9c9ea58261759 100644 (file)
@@ -5,17 +5,22 @@
 #define SIG_DFL ((void*)0)
 #define SIG_IGN ((void*)1)
 
+#define SIG_BLOCK 1
+#define SIG_UNBLOCK 2
+#define SIG_SETMASK 3
+
 struct sigaction;
 
+void   runtime·raisesigpipe(void);
+void   runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
 void   runtime·sigpanic(void);
-void   runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
+
+void   runtime·setitimer(int32, Itimerval*, Itimerval*);
 void   runtime·sigaction(int32, struct sigaction*, struct sigaction*);
-void   runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
+void   runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
 void   runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
-void   runtime·setitimer(int32, Itimerval*, Itimerval*);
+Sigset runtime·sigprocmask(int32, Sigset);
 int32  runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
 
-void   runtime·raisesigpipe(void);
-
 #define        NSIG 33
 #define        SI_USER 0
index 8b4f624e7cb7d487cf578d1876e3d5b26c9462dc..2f47ffc8435911dc77a86b612fd187af6d7264a6 100644 (file)
@@ -70,8 +70,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
                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
+               // Only push runtime·sigpanic if r->sc_rip != 0.
+               // If r->sc_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
@@ -133,8 +133,8 @@ runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
        sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
        if(restart)
                sa.sa_flags |= SA_RESTART;
-       sa.sa_mask = ~0ULL;
-       if (fn == runtime·sighandler)
+       sa.sa_mask = ~0U;
+       if(fn == runtime·sighandler)
                fn = (void*)runtime·sigtramp;
        sa.__sigaction_u.__sa_sigaction = (void*)fn;
        runtime·sigaction(i, &sa, nil);
index 4d27e050d089de91e83ba4b399d4254d60435716..7140de86fcfc3bb9c777dfd8f8c21b3566a5120d 100644 (file)
@@ -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",
index 593b4a9df29e139c141147c5adac04a50be4ef99..22505c4f02fb8c098d07a2169dff6519db20ce1a 100644 (file)
@@ -135,6 +135,14 @@ TEXT runtime·sigaction(SB),7,$-4
        MOVL    $0xf1, 0xf1  // crash
        RET
 
+TEXT runtime·sigprocmask(SB),7,$-4
+       MOVL    $48, AX                 // sys_sigprocmask
+       INT     $0x80
+       JAE     2(PC)
+       MOVL    $0xf1, 0xf1  // crash
+       MOVL    AX, oset+0(FP)
+       RET
+
 TEXT runtime·sigtramp(SB),7,$44
        get_tls(CX)
 
index d2d48e6b568de8a58652bfe778dbcbbe266898a5..0c7093dd5c4dec314e2a0bb7bce3e35d6ae75c6e 100644 (file)
@@ -173,6 +173,16 @@ TEXT runtime·sigaction(SB),7,$-8
        MOVL    $0xf1, 0xf1  // crash
        RET
 
+TEXT runtime·sigprocmask(SB),7,$0
+       MOVL    8(SP), DI               // arg 1 - how
+       MOVL    12(SP), SI              // arg 2 - set
+       MOVL    $48, AX                 // sys_sigprocmask
+       SYSCALL
+       JCC     2(PC)
+       MOVL    $0xf1, 0xf1  // crash
+       MOVL    AX, oset+0(FP)          // Return oset
+       RET
+
 TEXT runtime·sigtramp(SB),7,$64
        get_tls(BX)
        
index d0f9472106c80f3d10b9d7364115e603fbd5370f..d9ce6d602877f9c2ce589b9935e82135bf3e5e65 100644 (file)
@@ -20,6 +20,9 @@ enum
 
 extern SigTab runtime·sigtab[];
 
+static Sigset sigset_all = ~(Sigset)0;
+static Sigset sigset_none;
+
 extern int64 runtime·rfork_thread(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
 extern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock);
 extern int32 runtime·thrwakeup(void *ident, int32 n);
@@ -128,6 +131,7 @@ runtime·semawakeup(M *mp)
 void
 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
 {
+       Sigset oset;
        int32 flags;
        int32 ret;
 
@@ -141,7 +145,11 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
 
        m->tls[0] = m->id;      // so 386 asm can find it
 
-       if((ret = runtime·rfork_thread(flags, stk, m, g, fn)) < 0) {
+       oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
+       ret = runtime·rfork_thread(flags, stk, m, g, fn);
+       runtime·sigprocmask(SIG_SETMASK, oset);
+
+       if(ret < 0) {
                runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret);
                if (ret == -ENOTSUP)
                        runtime·printf("runtime: is kern.rthreads disabled?\n");
@@ -168,6 +176,7 @@ runtime·minit(void)
        // Initialize signal handling
        m->gsignal = runtime·malg(32*1024);
        runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
+       runtime·sigprocmask(SIG_SETMASK, sigset_none);
 }
 
 void