Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Jan 2010 20:02:28 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r203176 - in stable/8/sys: kern sys
Message-ID:  <201001292002.o0TK2S0h060992@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001292002.o0TK2S0h060992>