This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix pldd not to leave process stopped after detaching


On 02/24/2014 10:41 AM, Andreas Schwab wrote:
> Wait for the inferior to enter ptrace-stop state before continuing, to
> close a race condition.
> 
> Andreas.
> 
> 	[BZ #15804]
> 	* elf/pldd.c (wait_for_ptrace_stop): New function.
> 	(main): Call it after attaching.

Looks good to me, and better than what we had before.

Note:
At some point we should reimplement this as PTRACE_SEIZE
and PTRACE_INTERRUPT if the minimum kernel is 3.4 or newer
which solves the still existing race conditions where
SIG_STOP could be lost and we can ignore the need to reinject
signals and check for errors.

> ---
>  elf/pldd.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/elf/pldd.c b/elf/pldd.c
> index 684aff4..75f7812 100644
> --- a/elf/pldd.c
> +++ b/elf/pldd.c
> @@ -34,6 +34,7 @@
>  #include <unistd.h>
>  #include <sys/ptrace.h>
>  #include <sys/stat.h>
> +#include <sys/wait.h>
>  
>  #include <ldsodefs.h>
>  #include <version.h>
> @@ -82,6 +83,7 @@ static char *exe;
>  
>  /* Local functions.  */
>  static int get_process_info (int dfd, long int pid);
> +static void wait_for_ptrace_stop (long int pid);
>  
>  
>  int
> @@ -170,6 +172,8 @@ main (int argc, char *argv[])
>  		 tid);
>  	}
>  
> +      wait_for_ptrace_stop (tid);
> +
>        struct thread_list *newp = alloca (sizeof (*newp));
>        newp->tid = tid;
>        newp->next = thread_list;
> @@ -194,6 +198,27 @@ main (int argc, char *argv[])
>  }
>  
>  
> +/* Wait for PID to enter ptrace-stop state after being attached.  */
> +static void
> +wait_for_ptrace_stop (long int pid)
> +{
> +  int status;
> +
> +  /* While waiting for SIGSTOP being delivered to the tracee we have to
> +     reinject any other pending signal.  Ignore all other errors.  */
> +  while (waitpid (pid, &status, __WALL) == pid && WIFSTOPPED (status))
> +    {
> +      /* The STOP signal should not be delivered to the tracee.  */
> +      if (WSTOPSIG (status) == SIGSTOP)
> +	return;
> +      if (ptrace (PTRACE_CONT, pid, NULL,
> +		  (void *) (uintptr_t) WSTOPSIG (status)))
> +	/* The only possible error is that the process died.  */
> +	return;
> +    }
> +}
> +
> +
>  /* Handle program arguments.  */
>  static error_t
>  parse_opt (int key, char *arg, struct argp_state *state)
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]