You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
1.7 KiB
65 lines
1.7 KiB
commit b04acb2651e0aaf615de50e9138cddfd5c24021f |
|
Author: Andreas Schwab <schwab@suse.de> |
|
Date: Tue Jul 30 11:58:45 2013 +0200 |
|
|
|
Fix race conditions in pldd that may leave the process stopped after detaching |
|
|
|
Fixes bug 15804 |
|
|
|
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)
|
|
|