[hpux/ttrace] Determine attached process LWP immediately after attaching.
authorJoel Brobecker <brobecker@gnat.com>
Thu, 13 Jan 2011 16:23:33 +0000 (16:23 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Thu, 13 Jan 2011 16:23:33 +0000 (16:23 +0000)
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/ChangeLog
gdb/inf-ttrace.c

index d0c31a0ba09e749d60f62cf0e1abb7eb958ae8be..e8acfd8ce3d00620dd212881d544d4432a1220a5 100644 (file)
@@ -1,3 +1,10 @@
+2011-01-13  Joel Brobecker  <brobecker@adacore.com>
+
+       [ttrace] Compute thread list immediately after attach.
+       * inf_ttrace_attach (inf_ttrace_create_threads_after_attach):
+       New subprogram.
+       (inf_ttrace_attach): Use it.
+
 2011-01-13  Joel Brobecker  <brobecker@adacore.com>
 
        * libunwind-frame.c (libunwind_frame_cache): Do not return NULL
index d559067bb17af050bc7d51e2012d43672a3988d4..ab075db9c4450e67c56d960e36a18e34da0bb34f 100644 (file)
@@ -683,6 +683,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)
 {
@@ -735,11 +782,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