Skip to content

Commit

Permalink
Fix race conditions in pldd that may leave the process stopped after …
Browse files Browse the repository at this point in the history
…detaching

Fixes bug 15804
  • Loading branch information
Andreas Schwab committed Feb 25, 2014
1 parent d4ec6ae commit b04acb2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2014-02-24 Andreas Schwab <schwab@suse.de>

[BZ #15804]
* elf/pldd.c (wait_for_ptrace_stop): New function.
(main): Call it after attaching.

2014-02-22 Roland McGrath <roland@hack.frob.com>

* Makerules ($(common-objpfx)Versions.v.i): No longer depend
Expand Down
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Version 2.20

* The following bugs are resolved with this release:

15894, 16447, 16545, 16574, 16600, 16609, 16610, 16611.
15804, 15894, 16447, 16545, 16574, 16600, 16609, 16610, 16611.

* The am33 port, which had not worked for several years, has been removed
from ports.
Expand Down
25 changes: 25 additions & 0 deletions elf/pldd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down

0 comments on commit b04acb2

Please sign in to comment.