mirror of
https://github.com/golang/go
synced 2024-11-21 22:04:39 -07:00
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
This commit is contained in:
parent
fe5b4a2f9b
commit
b0891060ae
@ -2,7 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/signalvar.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
@ -25,14 +28,21 @@ void
|
|||||||
libcgo_sys_thread_start(ThreadStart *ts)
|
libcgo_sys_thread_start(ThreadStart *ts)
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
|
sigset_t ign, oset;
|
||||||
pthread_t p;
|
pthread_t p;
|
||||||
size_t size;
|
size_t size;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
SIGFILLSET(ign);
|
||||||
|
sigprocmask(SIG_SETMASK, &ign, &oset);
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
ts->g->stackguard = size;
|
ts->g->stackguard = size;
|
||||||
err = pthread_create(&p, &attr, threadentry, ts);
|
err = pthread_create(&p, &attr, threadentry, ts);
|
||||||
|
|
||||||
|
sigprocmask(SIG_SETMASK, &oset, nil);
|
||||||
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
|
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
|
||||||
abort();
|
abort();
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/signalvar.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
@ -25,14 +28,22 @@ void
|
|||||||
libcgo_sys_thread_start(ThreadStart *ts)
|
libcgo_sys_thread_start(ThreadStart *ts)
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
|
sigset_t ign, oset;
|
||||||
pthread_t p;
|
pthread_t p;
|
||||||
size_t size;
|
size_t size;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
SIGFILLSET(ign);
|
||||||
|
sigprocmask(SIG_SETMASK, &ign, &oset);
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
|
|
||||||
ts->g->stackguard = size;
|
ts->g->stackguard = size;
|
||||||
err = pthread_create(&p, &attr, threadentry, ts);
|
err = pthread_create(&p, &attr, threadentry, ts);
|
||||||
|
|
||||||
|
sigprocmask(SIG_SETMASK, &oset, nil);
|
||||||
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
|
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
|
||||||
abort();
|
abort();
|
||||||
|
@ -7,6 +7,7 @@ void runtime·sigpanic(void);
|
|||||||
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
|
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
|
||||||
struct sigaction;
|
struct sigaction;
|
||||||
void runtime·sigaction(int32, struct sigaction*, 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 runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
|
||||||
void runtiem·setitimerval(int32, Itimerval*, Itimerval*);
|
void runtiem·setitimerval(int32, Itimerval*, Itimerval*);
|
||||||
void runtime·setitimer(int32, Itimerval*, Itimerval*);
|
void runtime·setitimer(int32, Itimerval*, Itimerval*);
|
||||||
|
@ -304,4 +304,17 @@ TEXT runtime·osyield(SB),7,$-4
|
|||||||
INT $0x80
|
INT $0x80
|
||||||
RET
|
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
|
GLOBL runtime·tlsoffset(SB),$4
|
||||||
|
@ -26,7 +26,7 @@ TEXT runtime·thr_new(SB),7,$0
|
|||||||
RET
|
RET
|
||||||
|
|
||||||
TEXT runtime·thr_start(SB),7,$0
|
TEXT runtime·thr_start(SB),7,$0
|
||||||
MOVQ DI, R13 // m
|
MOVQ DI, R13 // m
|
||||||
|
|
||||||
// set up FS to point at m->tls
|
// set up FS to point at m->tls
|
||||||
LEAQ m_tls(R13), DI
|
LEAQ m_tls(R13), DI
|
||||||
@ -233,3 +233,13 @@ TEXT runtime·osyield(SB),7,$-4
|
|||||||
MOVL $331, AX // sys_sched_yield
|
MOVL $331, AX // sys_sched_yield
|
||||||
SYSCALL
|
SYSCALL
|
||||||
RET
|
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 CTL_HW 6
|
||||||
#define HW_NCPU 3
|
#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
|
static int32
|
||||||
getncpu(void)
|
getncpu(void)
|
||||||
{
|
{
|
||||||
@ -77,6 +80,7 @@ void
|
|||||||
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
|
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
|
||||||
{
|
{
|
||||||
ThrParam param;
|
ThrParam param;
|
||||||
|
Sigset oset;
|
||||||
|
|
||||||
USED(fn); // thr_start assumes fn == mstart
|
USED(fn); // thr_start assumes fn == mstart
|
||||||
USED(g); // thr_start assumes g == m->g0
|
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);
|
stk, m, g, fn, m->id, m->tls[0], &m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runtime·sigprocmask(&sigset_all, &oset);
|
||||||
runtime·memclr((byte*)¶m, sizeof param);
|
runtime·memclr((byte*)¶m, sizeof param);
|
||||||
|
|
||||||
param.start_func = runtime·thr_start;
|
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
|
m->tls[0] = m->id; // so 386 asm can find it
|
||||||
|
|
||||||
runtime·thr_new(¶m, sizeof param);
|
runtime·thr_new(¶m, sizeof param);
|
||||||
|
runtime·sigprocmask(&oset, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -121,6 +127,7 @@ runtime·minit(void)
|
|||||||
// Initialize signal handling
|
// Initialize signal handling
|
||||||
m->gsignal = runtime·malg(32*1024);
|
m->gsignal = runtime·malg(32*1024);
|
||||||
runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
|
runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
|
||||||
|
runtime·sigprocmask(&sigset_none, nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user