svn commit: r203176 - in stable/8/sys: kern sys
Konstantin Belousov
kib at FreeBSD.org
Fri Jan 29 20:02:28 UTC 2010
Author: kib
Date: Fri Jan 29 20:02:28 2010
New Revision: 203176
URL: http://svn.freebsd.org/changeset/base/203176
Log:
MFC r202692:
Remove the signal from sigqueue before notifying the debugger for traced
process, fixing the race between resuming from stopped state and other
thread noting the old signal on the queue and acting.
Modified:
stable/8/sys/kern/kern_sig.c
stable/8/sys/sys/signalvar.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/kern/kern_sig.c
==============================================================================
--- stable/8/sys/kern/kern_sig.c Fri Jan 29 19:25:45 2010 (r203175)
+++ stable/8/sys/kern/kern_sig.c Fri Jan 29 20:02:28 2010 (r203176)
@@ -353,7 +353,10 @@ sigqueue_add(sigqueue_t *sq, int signo,
/* directly insert the ksi, don't copy it */
if (si->ksi_flags & KSI_INS) {
- TAILQ_INSERT_TAIL(&sq->sq_list, si, ksi_link);
+ if (si->ksi_flags & KSI_HEAD)
+ TAILQ_INSERT_HEAD(&sq->sq_list, si, ksi_link);
+ else
+ TAILQ_INSERT_TAIL(&sq->sq_list, si, ksi_link);
si->ksi_sigq = sq;
goto out_set_bit;
}
@@ -374,7 +377,10 @@ sigqueue_add(sigqueue_t *sq, int signo,
p->p_pendingcnt++;
ksiginfo_copy(si, ksi);
ksi->ksi_signo = signo;
- TAILQ_INSERT_TAIL(&sq->sq_list, ksi, ksi_link);
+ if (si->ksi_flags & KSI_HEAD)
+ TAILQ_INSERT_HEAD(&sq->sq_list, ksi, ksi_link);
+ else
+ TAILQ_INSERT_TAIL(&sq->sq_list, ksi, ksi_link);
ksi->ksi_sigq = sq;
}
@@ -2488,6 +2494,7 @@ issignal(struct thread *td, int stop_all
struct sigacts *ps;
struct sigqueue *queue;
sigset_t sigpending;
+ ksiginfo_t ksi;
int sig, prop, newsig;
p = td->td_proc;
@@ -2525,24 +2532,22 @@ issignal(struct thread *td, int stop_all
if (p->p_flag & P_TRACED && (p->p_flag & P_PPWAIT) == 0) {
/*
* If traced, always stop.
+ * Remove old signal from queue before the stop.
+ * XXX shrug off debugger, it causes siginfo to
+ * be thrown away.
*/
+ queue = &td->td_sigqueue;
+ ksi.ksi_signo = 0;
+ if (sigqueue_get(queue, sig, &ksi) == 0) {
+ queue = &p->p_sigqueue;
+ sigqueue_get(queue, sig, &ksi);
+ }
+
mtx_unlock(&ps->ps_mtx);
newsig = ptracestop(td, sig);
mtx_lock(&ps->ps_mtx);
if (sig != newsig) {
- ksiginfo_t ksi;
-
- queue = &td->td_sigqueue;
- /*
- * clear old signal.
- * XXX shrug off debugger, it causes siginfo to
- * be thrown away.
- */
- if (sigqueue_get(queue, sig, &ksi) == 0) {
- queue = &p->p_sigqueue;
- sigqueue_get(queue, sig, &ksi);
- }
/*
* If parent wants us to take the signal,
@@ -2557,10 +2562,20 @@ issignal(struct thread *td, int stop_all
* Put the new signal into td_sigqueue. If the
* signal is being masked, look for other signals.
*/
- SIGADDSET(queue->sq_signals, sig);
+ sigqueue_add(queue, sig, NULL);
if (SIGISMEMBER(td->td_sigmask, sig))
continue;
signotify(td);
+ } else {
+ if (ksi.ksi_signo != 0) {
+ ksi.ksi_flags |= KSI_HEAD;
+ if (sigqueue_add(&td->td_sigqueue, sig,
+ &ksi) != 0)
+ ksi.ksi_signo = 0;
+ }
+ if (ksi.ksi_signo == 0)
+ sigqueue_add(&td->td_sigqueue, sig,
+ NULL);
}
/*
Modified: stable/8/sys/sys/signalvar.h
==============================================================================
--- stable/8/sys/sys/signalvar.h Fri Jan 29 19:25:45 2010 (r203175)
+++ stable/8/sys/sys/signalvar.h Fri Jan 29 20:02:28 2010 (r203176)
@@ -234,6 +234,7 @@ typedef struct ksiginfo {
#define KSI_EXT 0x02 /* Externally managed ksi. */
#define KSI_INS 0x04 /* Directly insert ksi, not the copy */
#define KSI_SIGQ 0x08 /* Generated by sigqueue, might ret EGAIN. */
+#define KSI_HEAD 0x10 /* Insert into head, not tail. */
#define KSI_COPYMASK (KSI_TRAP|KSI_SIGQ)
#define KSI_ONQ(ksi) ((ksi)->ksi_sigq != NULL)
More information about the svn-src-all
mailing list