mirror of
https://github.com/golang/go
synced 2024-11-19 15:05:00 -07:00
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
This commit is contained in:
parent
caedc603d4
commit
098b9dcf2f
@ -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·sigpanic(void);
|
||||
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
|
||||
void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
|
||||
void runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
|
||||
void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
|
||||
void runtime·setitimer(int32, Itimerval*, Itimerval*);
|
||||
int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
|
||||
|
||||
void runtime·raisesigpipe(void);
|
||||
void runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
|
||||
void runtime·sigpanic(void);
|
||||
|
||||
void runtime·setitimer(int32, Itimerval*, Itimerval*);
|
||||
void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
|
||||
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
|
||||
void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
|
||||
Sigset runtime·sigprocmask(int32, Sigset);
|
||||
int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
|
||||
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user