svn commit: r355146 - head/sys/kern
Konstantin Belousov
kostikbel at gmail.com
Wed Nov 27 20:53:42 UTC 2019
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;
More information about the svn-src-all
mailing list