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>