Date: Wed, 27 Nov 2019 22:53:33 +0200 From: Konstantin Belousov <kostikbel@gmail.com> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r355146 - head/sys/kern Message-ID: <20191127205333.GL10580@kib.kiev.ua> In-Reply-To: <201911272033.xARKXrDm014961@repo.freebsd.org> References: <201911272033.xARKXrDm014961@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Nov 27, 2019 at 08:33:53PM +0000, Konstantin Belousov wrote: > Author: kib > Date: Wed Nov 27 20:33:53 2019 > New Revision: 355146 > URL: https://svnweb.freebsd.org/changeset/base/355146 Ease the life of PTRACE_SYSCALL users when debuggee sleeps in sigsuspend(2) and sig{timed,}wait(2). If PT_TO_SCE or PT_TO_SCX were issued after the target already entered sleep in sigsuspend(2) or sigtimedwait(2), there is no debugging events generated until a relevant signal is delivered. As result, debugger hangs waiting for an event. Introduce spurious EINTR returned in that situations to help debugger to gain control earlier. [Sorry] > > Log: > Requested and tested by: kevans > Reviewed by: kevans (previous version), markj > Sponsored by: The FreeBSD Foundation > MFC after: 1 week > Differential revision: https://reviews.freebsd.org/D22546 > > Modified: > head/sys/kern/kern_sig.c > > Modified: head/sys/kern/kern_sig.c > ============================================================================== > --- head/sys/kern/kern_sig.c Wed Nov 27 20:33:49 2019 (r355145) > +++ head/sys/kern/kern_sig.c Wed Nov 27 20:33:53 2019 (r355146) > @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); > #include <sys/namei.h> > #include <sys/proc.h> > #include <sys/procdesc.h> > +#include <sys/ptrace.h> > #include <sys/posix4.h> > #include <sys/pioctl.h> > #include <sys/racct.h> > @@ -1252,11 +1253,13 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, > int error, sig, timo, timevalid = 0; > struct timespec rts, ets, ts; > struct timeval tv; > + bool traced; > > p = td->td_proc; > error = 0; > ets.tv_sec = 0; > ets.tv_nsec = 0; > + traced = false; > > if (timeout != NULL) { > if (timeout->tv_nsec >= 0 && timeout->tv_nsec < 1000000000) { > @@ -1309,6 +1312,11 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, > timo = 0; > } > > + if (traced) { > + error = EINTR; > + break; > + } > + > error = msleep(ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", timo); > > if (timeout != NULL) { > @@ -1320,6 +1328,16 @@ kern_sigtimedwait(struct thread *td, sigset_t waitset, > error = 0; > } > } > + > + /* > + * If PTRACE_SCE or PTRACE_SCX were set after > + * userspace entered the syscall, return spurious > + * EINTR after wait was done. Only do this as last > + * resort after rechecking for possible queued signals > + * and expired timeouts. > + */ > + if (error == 0 && (p->p_ptevents & PTRACE_SYSCALL) != 0) > + traced = true; > } > > new_block = saved_mask; > @@ -1532,6 +1550,14 @@ kern_sigsuspend(struct thread *td, sigset_t mask) > has_sig += postsig(sig); > } > mtx_unlock(&p->p_sigacts->ps_mtx); > + > + /* > + * If PTRACE_SCE or PTRACE_SCX were set after > + * userspace entered the syscall, return spurious > + * EINTR. > + */ > + if ((p->p_ptevents & PTRACE_SYSCALL) != 0) > + has_sig += 1; > } > PROC_UNLOCK(p); > td->td_errno = EINTR;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20191127205333.GL10580>