Commit b0891060 authored by Devon H. O'Dell's avatar Devon H. O'Dell Committed by Andrew Gerrand

runtime: fix FreeBSD signal handling around thread creation

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
parent fe5b4a2f
......@@ -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();
......
......@@ -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();
......
......@@ -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*);
......
......@@ -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
......@@ -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
......@@ -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
......
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