tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
_lwp_create change
Hello,
This issue came up recently with the go language signal tests failing.
The problem is that NetBSD copies the l_sigstk on lwp_creation and if
threads happen to get signals at the same time, then they share the
signal stack and they die (if sigaltstack is set). Go attempts to work
around this by blocking the signals (setting the signal mask on lwp
creation, and then calling sigaltstack() itself):
...
var uc ucontextt
getcontext(unsafe.Pointer(&uc))
uc.uc_flags = _UC_SIGMASK | _UC_CPU
uc.uc_link = nil
uc.uc_sigmask = sigset_all
lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp.g0, funcPC(netbsdMstart))
ret := lwp_create(unsafe.Pointer(&uc), 0, unsafe.Pointer(&mp.procid))
...
Unfortunately this does not work (setting the mask this way) so we have
to explicitly do it using sigprocmask(); then later in netbsdMstart(), we
also have to set the stack with sigaltstack()? Wouldn't it nice if setting
_UC_SIGMASK set the signal mask and setting _UC_STACK set the signal stack
on lwp creation? Here's an untested diff:
There are a few questions?
- the current _lwp_makecontext code calls getcontext(), so it sets
_UC_STACK and _UC_SIGMASK... We can ignore those settings if we
want (although I believe these already contain the right values)
for the existing _lwp_makecontext code by making LWP_UCONTEXT a
user flag, so only new code passes it. This overloads the meaning
of _UC_STACK on lwp creation to mean "set the signal stack".
- 32 bit processes need special treatment (to pass a regular ucontext_t
not a ucontext32_t)
What do you think?
christos
Index: sys/lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.173
diff -u -u -r1.173 lwp.h
--- sys/lwp.h 8 Apr 2017 00:25:50 -0000 1.173
+++ sys/lwp.h 19 Apr 2017 21:49:23 -0000
@@ -551,6 +551,7 @@
#define LWP_SUSPENDED 0x00000080
/* Kernel-internal flags for LWP creation. */
+#define LWP_UCONTEXT 0x20000000
#define LWP_PIDLID 0x40000000
#define LWP_VFORK 0x80000000
Index: kern/kern_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v
retrieving revision 1.187
diff -u -u -r1.187 kern_lwp.c
--- kern/kern_lwp.c 14 Jan 2017 19:32:10 -0000 1.187
+++ kern/kern_lwp.c 19 Apr 2017 21:49:23 -0000
@@ -904,8 +904,12 @@
} else
l2->l_prflag = 0;
- l2->l_sigstk = l1->l_sigstk;
- l2->l_sigmask = l1->l_sigmask;
+ ucontext_t *uc = (flags & LWP_UCONTEXT) != 0 ? arg : NULL;
+
+ l2->l_sigstk = uc && (uc->uc_flags & _UC_STACK) ? uc->uc_stack :
+ l1->l_sigstk;
+ l2->l_sigmask = uc && (uc->uc_flags & _UC_SIGMASK) ? uc->uc_sigmask :
+ l1->l_sigmask;
TAILQ_INIT(&l2->l_sigpend.sp_info);
sigemptyset(&l2->l_sigpend.sp_set);
Index: kern/sys_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_lwp.c,v
retrieving revision 1.58
diff -u -u -r1.58 sys_lwp.c
--- kern/sys_lwp.c 15 Jan 2017 01:28:14 -0000 1.58
+++ kern/sys_lwp.c 19 Apr 2017 21:49:24 -0000
@@ -84,7 +84,11 @@
if (__predict_false(uaddr == 0))
return ENOMEM;
- error = lwp_create(l, p, uaddr, flags & LWP_DETACHED,
+ flags &= LWP_DETACHED;
+ // XXX: notyet LWP_UCONTEXT is bad for netbsd32
+ flags |= (p->p_flags & PK_32) ? 0 : LWP_UCONTEXT;
+
+ error = lwp_create(l, p, uaddr, flags,
NULL, 0, p->p_emul->e_startlwp, arg, &l2, l->l_class);
if (__predict_false(error)) {
uvm_uarea_free(uaddr);
Home |
Main Index |
Thread Index |
Old Index