[PATCH] Try to use PTRACE_SETOPTIONS to handle non-ptrace SIGTRAP

Roland McGrath roland at redhat.com
Fri Jul 23 01:12:14 UTC 2010


> diff --git a/process.c b/process.c
> index dadf830..ff78ff0 100644
> --- a/process.c
> +++ b/process.c
> @@ -1732,9 +1732,10 @@ struct tcb *tcp;
>  		fixvfork(tcp);
>  #endif /* SUNOS4 */
>  #if defined LINUX && defined TCB_WAITEXECVE
> -	if (exiting(tcp) && syserror(tcp))
> -		tcp->flags &= ~TCB_WAITEXECVE;
> -	else
> +	if (exiting(tcp)) {
> +		if (syserror(tcp))
> +			tcp->flags &= ~TCB_WAITEXECVE;
> +	} else

This code needs comments.  Furthermore, the actual behavior of Linux
kernels where TCB_WAITEXECVE is needed (i.e. PTRACE_O_TRACEEXEC not
supported or not yet in force) is that a normal SIGTRAP signal is
generated, so the normal ptrace signal stop for that comes only after
the syscall-exit stop for the execve call completing.  Hence, even
before the PTRACE_O_TRACEEXEC support, we should change this code to
only ever set TCB_WAITEXECVE in the first place with:
	if (exiting(tcp) && !syserror(tcp))
	
> +#ifdef USE_PTRACE_SETOPTIONS
> +
> +static int use_ptrace_setoptions = 1;
> +static int probe_ptrace_setoptions = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC;

These variables need comments explaining their meanings.
Also, I don't see a reason for having use_ptrace_setoptions.
The (probe_ptrace_setoptions == 0) test looks sufficient for the tests.

> +		/* Ignore post-execve trap. */
> +		if (is_post_execve_trap(tcp, status)) {
> +#ifdef TCB_WAITEXECVE
> +			tcp->flags &= ~TCB_WAITEXECVE;
> +#endif
> +			goto tracing;
> +		}

Perhaps the flag magic should go inside is_post_execve_trap too.

> +is_ptrace_stop(struct tcb *tcp, int status)
> +{
> +	if (tcp->flags & TCB_STARTUP)
> +		/* Didn't have the chance to set ptrace options yet.  */
> +		return WSTOPSIG(status) == SIGTRAP;

When internal_fork forces CLONE_PTRACE (or later if we start using
PTRACE_O_TRACE{CLONE,FORK,VFORK}, same thing), the new child inherits
the PTRACE_O_* settings from its creator.  So it doesn't need to get a
PTRACE_SETOPTIONS call at all, in fact.

The set_ptrace_options call could be conditional on tcp->parent == NULL
to cover that, I think.  Note that makes it consistent with the case
where the child reports before the parent syscall-exit report, where
internal_fork will then notice the TCB_SUSPENDED child--but you didn't
add a set_ptrace_options call there (as, indeed, it's not needed).

The code of course should get some comments about this subtlety.

This might be relevant in is_ptrace_stop too.  But, in fact the child
seen first doesn't get TCB_STARTUP, so I guess it will in fact be
understood correctly.


Thanks,
Roland




More information about the Strace-devel mailing list