]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix FreeBSD signal handling around thread creation
authorDevon H. O'Dell <devon.odell@gmail.com>
Wed, 22 Feb 2012 04:44:09 +0000 (15:44 +1100)
committerAndrew Gerrand <adg@golang.org>
Wed, 22 Feb 2012 04:44:09 +0000 (15:44 +1100)
Ignore signals while we are spawning a new thread. Previously, a
signal arriving just before runtime.minit setting up the signal
handler triggers a "double fault" in signal trampolining.
Fixes #3017.

R=rsc, mikioh.mikioh, minux.ma, adg
CC=golang-dev
https://golang.org/cl/5684060

src/pkg/runtime/cgo/gcc_freebsd_386.c
src/pkg/runtime/cgo/gcc_freebsd_amd64.c
src/pkg/runtime/os_freebsd.h
src/pkg/runtime/sys_freebsd_386.s
src/pkg/runtime/sys_freebsd_amd64.s
src/pkg/runtime/thread_freebsd.c

index ad9468730771f9f5d6939204a59b2c2b9a167d32..2c97e2a33037314ad5427e55764b13dbab6f3341 100644 (file)
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include <sys/types.h>
+#include <sys/signalvar.h>
 #include <pthread.h>
+#include <signal.h>
 #include "libcgo.h"
 
 static void* threadentry(void*);
@@ -25,14 +28,21 @@ void
 libcgo_sys_thread_start(ThreadStart *ts)
 {
        pthread_attr_t attr;
+       sigset_t ign, oset;
        pthread_t p;
        size_t size;
        int err;
 
+       SIGFILLSET(ign);
+       sigprocmask(SIG_SETMASK, &ign, &oset);
+
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
        ts->g->stackguard = size;
        err = pthread_create(&p, &attr, threadentry, ts);
+
+       sigprocmask(SIG_SETMASK, &oset, nil);
+
        if (err != 0) {
                fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
                abort();
index b18d1bc67da91bdb2e20e1a873db5fd74e5eacc6..3beb4d7bb8620d5fcfdd68b9eee8c7d3910286ca 100644 (file)
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include <sys/types.h>
+#include <sys/signalvar.h>
 #include <pthread.h>
+#include <signal.h>
 #include "libcgo.h"
 
 static void* threadentry(void*);
@@ -25,14 +28,22 @@ void
 libcgo_sys_thread_start(ThreadStart *ts)
 {
        pthread_attr_t attr;
+       sigset_t ign, oset;
        pthread_t p;
        size_t size;
        int err;
 
+       SIGFILLSET(ign);
+       sigprocmask(SIG_SETMASK, &ign, &oset);
+
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &size);
+
        ts->g->stackguard = size;
        err = pthread_create(&p, &attr, threadentry, ts);
+
+       sigprocmask(SIG_SETMASK, &oset, nil);
+
        if (err != 0) {
                fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
                abort();
index 03f131a52437ae1c57da3a56c00bf3e3d5d78502..194d96320d0c119ef6685bb1ac44697343b414bb 100644 (file)
@@ -7,6 +7,7 @@ void    runtime·sigpanic(void);
 void   runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
 struct sigaction;
 void   runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void   runtime·sigprocmask(Sigset *, Sigset *);
 void   runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
 void   runtiem·setitimerval(int32, Itimerval*, Itimerval*);
 void   runtime·setitimer(int32, Itimerval*, Itimerval*);
index 9f31e253f10336ce86fdfbbce71a2fb03e81d39e..0e03eac35ad39f769bcb0d90350476ce622a641c 100644 (file)
@@ -304,4 +304,17 @@ TEXT runtime·osyield(SB),7,$-4
        INT     $0x80
        RET
 
+TEXT runtime·sigprocmask(SB),7,$16
+       MOVL    $0, 0(SP)               // syscall gap
+       MOVL    $3, 4(SP)               // arg 1 - how (SIG_SETMASK)
+       MOVL    args+0(FP), AX
+       MOVL    AX, 8(SP)               // arg 2 - set
+       MOVL    args+4(FP), AX
+       MOVL    AX, 12(SP)              // arg 3 - oset
+       MOVL    $340, AX                // sys_sigprocmask
+       INT     $0x80
+       JAE     2(PC)
+       CALL    runtime·notok(SB)
+       RET
+
 GLOBL runtime·tlsoffset(SB),$4
index fbed690d1851e3f1b18a6684f989f2e386e13afd..8021a4248a14e659cad3d7fd8c35dd1219f357d0 100644 (file)
@@ -26,7 +26,7 @@ TEXT runtime·thr_new(SB),7,$0
        RET
 
 TEXT runtime·thr_start(SB),7,$0
-       MOVQ    DI, R13 // m
+       MOVQ    DI, R13 // m
 
        // set up FS to point at m->tls
        LEAQ    m_tls(R13), DI
@@ -233,3 +233,13 @@ TEXT runtime·osyield(SB),7,$-4
        MOVL    $331, AX                // sys_sched_yield
        SYSCALL
        RET
+
+TEXT runtime·sigprocmask(SB),7,$0
+       MOVL    $3, DI                  // arg 1 - how (SIG_SETMASK)
+       MOVQ    8(SP), SI               // arg 2 - set
+       MOVQ    16(SP), DX              // arg 3 - oset
+       MOVL    $340, AX                // sys_sigprocmask
+       SYSCALL
+       JAE     2(PC)
+       CALL    runtime·notok(SB)
+       RET
index 06e3a59d002a3d4b1ee0369520d393e8ac81631f..04de03711d06c1039db40c4f4ae135e89493aeba 100644 (file)
@@ -13,6 +13,9 @@ extern int32 runtime·sys_umtx_op(uint32*, int32, uint32, void*, void*);
 #define        CTL_HW  6
 #define        HW_NCPU 3
 
+static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
+static Sigset sigset_none = { 0, 0, 0, 0, };
+
 static int32
 getncpu(void)
 {
@@ -77,6 +80,7 @@ void
 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
 {
        ThrParam param;
+       Sigset oset;
 
        USED(fn);       // thr_start assumes fn == mstart
        USED(g);        // thr_start assumes g == m->g0
@@ -86,6 +90,7 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
                        stk, m, g, fn, m->id, m->tls[0], &m);
        }
 
+       runtime·sigprocmask(&sigset_all, &oset);
        runtime·memclr((byte*)&param, sizeof param);
 
        param.start_func = runtime·thr_start;
@@ -100,6 +105,7 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
        m->tls[0] = m->id;      // so 386 asm can find it
 
        runtime·thr_new(&param, sizeof param);
+       runtime·sigprocmask(&oset, nil);
 }
 
 void
@@ -121,6 +127,7 @@ runtime·minit(void)
        // Initialize signal handling
        m->gsignal = runtime·malg(32*1024);
        runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
+       runtime·sigprocmask(&sigset_none, nil);
 }
 
 void