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