diff options
author | Luis Machado <luisgpm@br.ibm.com> | 2011-08-24 12:17:39 +0000 |
---|---|---|
committer | Luis Machado <luisgpm@br.ibm.com> | 2011-08-24 12:17:39 +0000 |
commit | e3deef738cf04479b2114ddb3b1dfb5f18a9b409 (patch) | |
tree | 7c92cb02c6ecbfee317de67f85804649464c5a6b /gdb/gdbserver/linux-low.c | |
parent | 13da1c9782f523debe697aa1415b7b4f96fe4f93 (diff) | |
download | gdb-e3deef738cf04479b2114ddb3b1dfb5f18a9b409.zip gdb-e3deef738cf04479b2114ddb3b1dfb5f18a9b409.tar.gz gdb-e3deef738cf04479b2114ddb3b1dfb5f18a9b409.tar.bz2 |
Stop threads when attaching to a PID that is the tgid.
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r-- | gdb/gdbserver/linux-low.c | 75 |
1 files changed, 72 insertions, 3 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 0aab032..94f785c 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -26,6 +26,7 @@ #include <sys/param.h> #include <sys/ptrace.h> #include "linux-ptrace.h" +#include "linux-procfs.h" #include <signal.h> #include <sys/ioctl.h> #include <fcntl.h> @@ -586,7 +587,9 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial) } if (initial) - /* NOTE/FIXME: This lwp might have not been the tgid. */ + /* If lwp is the tgid, we handle adding existing threads later. + Otherwise we just add lwp without bothering about any other + threads. */ ptid = ptid_build (lwpid, lwpid, 0); else { @@ -621,8 +624,10 @@ linux_attach_lwp_1 (unsigned long lwpid, int initial) In this case we want the process thread to stop. This is handled by having linux_attach set last_resume_kind == resume_stop after we return. - ??? If the process already has several threads we leave the other - threads running. + + If the pid we are attaching to is also the tgid, we attach to and + stop all the existing threads. Otherwise, we attach to pid and + ignore any other threads in the same group as this pid. 3) GDB is connecting to gdbserver and is requesting an enumeration of all existing threads. @@ -646,9 +651,14 @@ linux_attach_lwp (unsigned long lwpid) linux_attach_lwp_1 (lwpid, 0); } +/* Attach to PID. If PID is the tgid, attach to it and all + of its threads. */ + int linux_attach (unsigned long pid) { + /* Attach to PID. We will check for other threads + soon. */ linux_attach_lwp_1 (pid, 1); linux_add_process (pid, 1); @@ -662,6 +672,65 @@ linux_attach (unsigned long pid) thread->last_resume_kind = resume_stop; } + if (linux_proc_get_tgid (pid) == pid) + { + DIR *dir; + char pathname[128]; + + sprintf (pathname, "/proc/%ld/task", pid); + + dir = opendir (pathname); + + if (!dir) + { + fprintf (stderr, "Could not open /proc/%ld/task.\n", pid); + fflush (stderr); + } + else + { + /* At this point we attached to the tgid. Scan the task for + existing threads. */ + unsigned long lwp; + int new_threads_found; + int iterations = 0; + struct dirent *dp; + + while (iterations < 2) + { + new_threads_found = 0; + /* Add all the other threads. While we go through the + threads, new threads may be spawned. Cycle through + the list of threads until we have done two iterations without + finding new threads. */ + while ((dp = readdir (dir)) != NULL) + { + /* Fetch one lwp. */ + lwp = strtoul (dp->d_name, NULL, 10); + + /* Is this a new thread? */ + if (lwp + && find_thread_ptid (ptid_build (pid, lwp, 0)) == NULL) + { + linux_attach_lwp_1 (lwp, 0); + new_threads_found++; + + if (debug_threads) + fprintf (stderr, "\ +Found and attached to new lwp %ld\n", lwp); + } + } + + if (!new_threads_found) + iterations++; + else + iterations = 0; + + rewinddir (dir); + } + closedir (dir); + } + } + return 0; } |