NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/36183: problem with ptrace and multithreaded processes
Here's a workaround patch from ad
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sig.c,v
retrieving revision 1.289
diff -u -p -u -r1.289 kern_sig.c
--- sys/kern/kern_sig.c 24 Oct 2008 18:07:36 -0000 1.289
+++ sys/kern/kern_sig.c 15 Nov 2008 10:57:48 -0000
@@ -1653,9 +1653,9 @@ sigswitch(bool ppsig, int ppmask, int si
*/
KERNEL_UNLOCK_ALL(l, &biglocks);
if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) {
+ KASSERT(l->l_stat == LSONPROC);
p->p_nrlwps--;
lwp_lock(l);
- KASSERT(l->l_stat == LSONPROC || l->l_stat == LSSLEEP);
l->l_stat = LSSTOP;
lwp_unlock(l);
}
@@ -1684,19 +1684,25 @@ sigchecktrace(sigpend_t **spp)
* If we are no longer being traced, or the parent didn't
* give us a signal, look for more signals.
*/
- if ((p->p_slflag & PSL_TRACED) == 0 || p->p_xstat == 0)
+ if ((p->p_slflag & PSL_TRACED) == 0 ||
+ p->p_xstat == 0 || p->p_xlwp != l)
return 0;
- /* If there's a pending SIGKILL, process it immediately. */
- if (sigismember(&p->p_sigpend.sp_set, SIGKILL))
+ /*
+ * If there's a pending SIGKILL or the process is on the way
+ * out, process immediately.
+ */
+ if (sigismember(&p->p_sigpend.sp_set, SIGKILL) ||
+ (l->l_flag & (LW_WCORE | LW_WEXIT)) != 0)
return 0;
/*
- * If the new signal is being masked, look for other signals.
- * `p->p_sigctx.ps_siglist |= mask' is done in setrunnable().
+ * sigaddset() is done in setrunnable().
*/
signo = p->p_xstat;
+ *spp = &l->l_sigpend;
p->p_xstat = 0;
+ p->p_xlwp = NULL;
if ((sigprop[signo] & SA_TOLWP) != 0)
*spp = &l->l_sigpend;
else
@@ -1956,11 +1962,24 @@ postsig(int signo)
}
/*
+ * If the process is exiting or dumping core (possible after the
+ * unlock above), then bail out now. Both of these conditions
+ * will be visible with only the proc mutex held. Note that the
+ * call to lwp_userret() is recursive, but we will not come back
+ * this way.
+ */
+ if ((l->l_flag & (LW_WEXIT | LW_WCORE)) != 0) {
+ lwp_userret(l);
+ panic("postsig userret");
+ /* NOTREACHED */
+ }
+
+ /*
* If we get here, the signal must be caught.
*/
#ifdef DIAGNOSTIC
if (action == SIG_IGN || sigismember(&l->l_sigmask, signo))
- panic("postsig action");
+ panic("postsig: action");
#endif
kpsendsig(l, &ksi, returnmask);
@@ -2261,6 +2280,7 @@ proc_unstop(struct proc *p)
p->p_stat = SACTIVE;
p->p_sflag &= ~PS_STOPPING;
+ p->p_xlwp = NULL;
sig = p->p_xstat;
if (!p->p_waited)
@@ -2276,15 +2296,21 @@ proc_unstop(struct proc *p)
setrunnable(l);
continue;
}
- if (sig && (l->l_flag & LW_SINTR) != 0) {
- setrunnable(l);
+ if (sig && (l->l_flag & LW_SINTR) != 0 &&
+ !sigismember(&l->l_sigmask, sig)) {
sig = 0;
+ setrunnable(l);
} else {
l->l_stat = LSSLEEP;
p->p_nrlwps++;
lwp_unlock(l);
}
}
+
+ if (p->p_xlwp == NULL) {
+ /* No LWP available to take the signal. */
+ p->p_xstat = 0;
+ }
}
static int
Index: sys/kern/kern_synch.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_synch.c,v
retrieving revision 1.255
diff -u -p -u -r1.255 kern_synch.c
--- sys/kern/kern_synch.c 15 Nov 2008 10:54:32 -0000 1.255
+++ sys/kern/kern_synch.c 15 Nov 2008 10:57:49 -0000
@@ -925,7 +925,6 @@ setrunnable(struct lwp *l)
{
struct proc *p = l->l_proc;
struct cpu_info *ci;
- sigset_t *ss;
KASSERT((l->l_flag & LW_IDLE) == 0);
KASSERT(mutex_owned(p->p_lock));
@@ -938,13 +937,12 @@ setrunnable(struct lwp *l)
* If we're being traced (possibly because someone attached us
* while we were stopped), check for a signal from the debugger.
*/
- if ((p->p_slflag & PSL_TRACED) != 0 && p->p_xstat != 0) {
- if ((sigprop[p->p_xstat] & SA_TOLWP) != 0)
- ss = &l->l_sigpend.sp_set;
- else
- ss = &p->p_sigpend.sp_set;
- sigaddset(ss, p->p_xstat);
+ if ((p->p_slflag & PSL_TRACED) != 0 && p->p_xstat != 0 &&
+ p->p_xlwp == NULL &&
+ !sigismember(&l->l_sigmask, p->p_xstat)) {
+ sigaddset(&l->l_sigpend.sp_set, p->p_xstat);
signotify(l);
+ p->p_xlwp = l;
}
p->p_nrlwps++;
break;
Index: sys/sys/proc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/proc.h,v
retrieving revision 1.282
diff -u -p -u -r1.282 proc.h
--- sys/sys/proc.h 22 Oct 2008 11:14:33 -0000 1.282
+++ sys/sys/proc.h 15 Nov 2008 10:57:49 -0000
@@ -290,6 +290,7 @@ struct proc {
LIST_HEAD(, lwp) p_sigwaiters; /* p: LWPs waiting for signals */
sigstore_t p_sigstore; /* p: process-wide signal state */
sigpend_t p_sigpend; /* p: pending signals */
+ struct lwp *p_xlwp; /* s: LWP to take sig from debugger */
struct lcproc *p_lwpctl; /* p, a: _lwp_ctl() information */
pid_t p_ppid; /* :: cached parent pid */
Home |
Main Index |
Thread Index |
Old Index