From owner-svn-src-stable@FreeBSD.ORG Fri Jan 29 20:02:28 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 971631065670; Fri, 29 Jan 2010 20:02:28 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 848A68FC17; Fri, 29 Jan 2010 20:02:28 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o0TK2SpN060995; Fri, 29 Jan 2010 20:02:28 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0TK2S0h060992; Fri, 29 Jan 2010 20:02:28 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201001292002.o0TK2S0h060992@svn.freebsd.org> From: Konstantin Belousov Date: Fri, 29 Jan 2010 20:02:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r203176 - in stable/8/sys: kern sys X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Jan 2010 20:02:28 -0000 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)