Commit 098b9dcf authored by Joel Sing's avatar Joel Sing

runtime: block signals during thread creation on openbsd

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
parent caedc603
......@@ -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
......@@ -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);
......
......@@ -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",
......
......@@ -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)
......
......@@ -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)
......
......@@ -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
......
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