[PATCH 5/8] inf-ttrace: Determine attached process LWP immediately after attaching.

Joel Brobecker
2010-12-28T04:43:50Z

When attaching to a process, the ttrace interface was creating a ptid
with a null LWP, because it did not have it yet. This LWP was then
set as soon as we received our first event from our inferior, during
our first wait. Similarly, the allocation of the thread private info
was also defered.

This works on PA/HP-UX, because we immediately perform a wait to pop
the event triggered by the attach. We can use that event to extract
the thread's LWP. But this does not work for IA64/HP-UX, because
the attach no longer triggers an event, and thus a wait should NOT
be performed (such a wait would simply block indefinitely).

It is actually possible, however, to determine the thread's LWP.
This change therefore adjusts the attach code to create a thread with
the correct LWP set, as well as with its private info allocated.
Same thing for all the other threads.

gdb/ChangeLog:

[ttrace] Compute thread list immediately after attach.
* inf_ttrace_attach (inf_ttrace_create_threads_after_attach):
New subprogram.
(inf_ttrace_attach): Use it.

---
gdb/inf-ttrace.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/gdb/inf-ttrace.c b/gdb/inf-ttrace.c
index fd394c6..24dc0f9 100644
--- a/gdb/inf-ttrace.c
+++ b/gdb/inf-ttrace.c
@@ -688,6 +688,53 @@ inf_ttrace_mourn_inferior (struct target_ops *ops)
generic_mourn_inferior ();
}

+/* Assuming we just attached the debugger to a new inferior, create
+ a new thread_info structure for each thread, and add it to our
+ list of threads. */
+
+static void
+inf_ttrace_create_threads_after_attach (int pid)
+{
+ int status;
+ ptid_t ptid;
+ ttstate_t tts;
+ struct thread_info *ti;
+
+ status = ttrace (TT_PROC_GET_FIRST_LWP_STATE, pid, 0,
+ (uintptr_t) &tts, sizeof (ttstate_t), 0);
+ if (status < 0)
+ perror_with_name (_("TT_PROC_GET_FIRST_LWP_STATE ttrace call failed"));
+ gdb_assert (tts.tts_pid == pid);
+
+ /* Add the stopped thread. */
+ ptid = ptid_build (pid, tts.tts_lwpid, 0);
+ ti = add_thread (ptid);
+ ti->private = xzalloc (sizeof (struct inf_ttrace_private_thread_info));
+ inf_ttrace_num_lwps++;
+
+ /* We use the "first stopped thread" as the currently active thread. */
+ inferior_ptid = ptid;
+
+ /* Iterative over all the remaining threads. */
+
+ for (;;)
+ {
+ ptid_t ptid;
+
+ status = ttrace (TT_PROC_GET_NEXT_LWP_STATE, pid, 0,
+ (uintptr_t) &tts, sizeof (ttstate_t), 0);
+ if (status < 0)
+ perror_with_name (_("TT_PROC_GET_NEXT_LWP_STATE ttrace call failed"));
+ if (status == 0)
+ break; /* End of list. */
+
+ ptid = ptid_build (tts.tts_pid, tts.tts_lwpid, 0);
+ ti = add_thread (ptid);
+ ti->private = xzalloc (sizeof (struct inf_ttrace_private_thread_info));
+ inf_ttrace_num_lwps++;
+ }
+}
+
static void
inf_ttrace_attach (struct target_ops *ops, char *args, int from_tty)
{
@@ -740,11 +787,7 @@ inf_ttrace_attach (struct target_ops *ops, char *args, int from_tty)

push_target (ops);

- /* We'll bump inf_ttrace_num_lwps up and add the private data to the
- thread as soon as we get to inf_ttrace_wait. At this point, we
- don't have lwpid info yet. */
- inferior_ptid = pid_to_ptid (pid);
- add_thread_silent (inferior_ptid);
+ inf_ttrace_create_threads_after_attach (pid);
}

static void
--
1.7.1