* inferior.h (notice_new_inferior): Declare.
authorPedro Alves <palves@redhat.com>
Wed, 4 Mar 2009 22:50:59 +0000 (22:50 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 4 Mar 2009 22:50:59 +0000 (22:50 +0000)
* infcmd.c (notice_new_inferior): New.
* remote.c (remote_add_inferior, remote_add_thread): New.
(notice_new_inferiors): Rename to...
(remote_notice_new_inferior): ... this.  Add RUNNING argument.
Use remote_add_thread instead of add_thread, passing it the
RUNNING argument.  Add an inferior with remote_add_inferior.  If
we just learned about an inferior, call notice_new_inferior.
(record_currthread): Adjust.
(remote_threads_info): Adjust to use remote_notice_new_inferior.
(remote_start_remote, extended_remote_attach_1): Use remote_add_inferior.
(process_stop_reply): Adjust.  Call remote_notice_new_inferior
after handling expedited registers and watchpoint state.
(extended_remote_create_inferior_1): Use remote_add_inferior.

gdb/ChangeLog
gdb/infcmd.c
gdb/inferior.h
gdb/remote.c

index 2bf365da5c2b924a2d7ed5e76f858c95b40f9742..f260965c59b759e20510c6cae3f8071af8d0c32d 100644 (file)
@@ -1,3 +1,20 @@
+2009-03-04  Pedro Alves  <pedro@codesourcery.com>
+
+       * inferior.h (notice_new_inferior): Declare.
+       * infcmd.c (notice_new_inferior): New.
+       * remote.c (remote_add_inferior, remote_add_thread): New.
+       (notice_new_inferiors): Rename to...
+       (remote_notice_new_inferior): ... this.  Add RUNNING argument.
+       Use remote_add_thread instead of add_thread, passing it the
+       RUNNING argument.  Add an inferior with remote_add_inferior.  If
+       we just learned about an inferior, call notice_new_inferior.
+       (record_currthread): Adjust.
+       (remote_threads_info): Adjust to use remote_notice_new_inferior.
+       (remote_start_remote, extended_remote_attach_1): Use remote_add_inferior.
+       (process_stop_reply): Adjust.  Call remote_notice_new_inferior
+       after handling expedited registers and watchpoint state.
+       (extended_remote_create_inferior_1): Use remote_add_inferior.
+
 2009-03-04  Aleksandar Ristovski  <aristovski@qnx.com>
 
        * infcmd.c (registers_info): Remove register number case.
index 37a237a12f6afbb90ebb391d9bf006310230057d..6aed426b7fc41dd900ae5fc1d5c68b5e043521bb 100644 (file)
@@ -2313,6 +2313,72 @@ attach_command (char *args, int from_tty)
   discard_cleanups (back_to);
 }
 
+/* We had just found out that the target was already attached to an
+   inferior.  PTID points at a thread of this new inferior, that is
+   the most likely to be stopped right now, but not necessarily so.
+   The new inferior is assumed to be already added to the inferior
+   list at this point.  If LEAVE_RUNNING, then leave the threads of
+   this inferior running, except those we've explicitly seen reported
+   as stopped.  */
+
+void
+notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
+{
+  struct cleanup* old_chain;
+  int async_exec;
+
+  old_chain = make_cleanup (null_cleanup, NULL);
+
+  /* If in non-stop, leave threads as running as they were.  If
+     they're stopped for some reason other than us telling it to, the
+     target reports a signal != TARGET_SIGNAL_0.  We don't try to
+     resume threads with such a stop signal.  */
+  async_exec = non_stop;
+
+  if (!ptid_equal (inferior_ptid, null_ptid))
+    make_cleanup_restore_current_thread ();
+
+  switch_to_thread (ptid);
+
+  /* When we "notice" a new inferior we need to do all the things we
+     would normally do if we had just attached to it.  */
+
+  if (is_executing (inferior_ptid))
+    {
+      struct inferior *inferior = current_inferior ();
+
+      /* We're going to install breakpoints, and poke at memory,
+        ensure that the inferior is stopped for a moment while we do
+        that.  */
+      target_stop (inferior_ptid);
+
+      inferior->stop_soon = STOP_QUIETLY_REMOTE;
+
+      /* Wait for stop before proceeding.  */
+      if (target_can_async_p ())
+       {
+         struct attach_command_continuation_args *a;
+
+         a = xmalloc (sizeof (*a));
+         a->args = xstrdup ("");
+         a->from_tty = from_tty;
+         a->async_exec = async_exec;
+         add_inferior_continuation (attach_command_continuation, a,
+                                    attach_command_continuation_free_args);
+
+         do_cleanups (old_chain);
+         return;
+       }
+      else
+       wait_for_inferior (0);
+    }
+
+  async_exec = leave_running;
+  attach_command_post_wait ("" /* args */, from_tty, async_exec);
+
+  do_cleanups (old_chain);
+}
+
 /*
  * detach_command --
  * takes a program previously attached to and detaches it.
index c4594112d3487a8144adb26b046a789524534995..6a1c01acd52df89c198d136da500438ce2c02e30 100644 (file)
@@ -281,6 +281,8 @@ extern void interrupt_target_1 (int all_threads);
 
 extern void detach_command (char *, int);
 
+extern void notice_new_inferior (ptid_t, int, int);
+
 /* Address at which inferior stopped.  */
 
 extern CORE_ADDR stop_pc;
index 6efad54bceef6063f1845585b39e0d95acce2f94..390924f4b54ed5e4bedab18a7d5419d0f374d21a 100644 (file)
@@ -1118,9 +1118,53 @@ static ptid_t any_thread_ptid;
 static ptid_t general_thread;
 static ptid_t continue_thread;
 
+/* Add PID to GDB's inferior table.  Since we can be connected to a
+   remote system before before knowing about any inferior, mark the
+   target with execution when we find the first inferior.  */
+
+static struct inferior *
+remote_add_inferior (int pid)
+{
+  struct remote_state *rs = get_remote_state ();
+  struct inferior *inf;
+
+  inf = add_inferior (pid);
+
+  /* This may be the first inferior we hear about.  */
+  if (!target_has_execution)
+    {
+      if (rs->extended)
+       target_mark_running (&extended_remote_ops);
+      else
+       target_mark_running (&remote_ops);
+    }
+
+  return inf;
+}
+
+/* Add thread PTID to GDB's thread list.  Tag it as executing/running
+   according to RUNNING.  */
+
 static void
-notice_new_inferiors (ptid_t currthread)
+remote_add_thread (ptid_t ptid, int running)
 {
+  add_thread (ptid);
+
+  set_executing (ptid, running);
+  set_running (ptid, running);
+}
+
+/* Come here when we learn about a thread id from the remote target.
+   It may be the first time we hear about such thread, so take the
+   opportunity to add it to GDB's thread list.  In case this is the
+   first time we're noticing its corresponding inferior, add it to
+   GDB's inferior list as well.  */
+
+static void
+remote_notice_new_inferior (ptid_t currthread, int running)
+{
+  struct remote_state *rs = get_remote_state ();
+
   /* If this is a new thread, add it to GDB's thread list.
      If we leave it up to WFI to do this, bad things will happen.  */
 
@@ -1128,12 +1172,14 @@ notice_new_inferiors (ptid_t currthread)
     {
       /* We're seeing an event on a thread id we knew had exited.
         This has to be a new thread reusing the old id.  Add it.  */
-      add_thread (currthread);
+      remote_add_thread (currthread, running);
       return;
     }
 
   if (!in_thread_list (currthread))
     {
+      struct inferior *inf = NULL;
+
       if (ptid_equal (pid_to_ptid (ptid_get_pid (currthread)), inferior_ptid))
        {
          /* inferior_ptid has no thread member yet.  This can happen
@@ -1161,10 +1207,16 @@ notice_new_inferiors (ptid_t currthread)
         may not know about it yet.  Add it before adding its child
         thread, so notifications are emitted in a sensible order.  */
       if (!in_inferior_list (ptid_get_pid (currthread)))
-       add_inferior (ptid_get_pid (currthread));
+       inf = remote_add_inferior (ptid_get_pid (currthread));
 
       /* This is really a new thread.  Add it.  */
-      add_thread (currthread);
+      remote_add_thread (currthread, running);
+
+      /* If we found a new inferior, let the common code do whatever
+        it needs to with it (e.g., read shared libraries, insert
+        breakpoints).  */
+      if (inf != NULL)
+       notice_new_inferior (currthread, running, 0);
     }
 }
 
@@ -1183,7 +1235,7 @@ record_currthread (ptid_t currthread)
     /* We're just invalidating the local thread mirror.  */
     return;
 
-  notice_new_inferiors (currthread);
+  remote_notice_new_inferior (currthread, 0);
 }
 
 static char *last_pass_packet;
@@ -2146,27 +2198,15 @@ remote_threads_info (struct target_ops *ops)
              do
                {
                  new_thread = read_ptid (bufp, &bufp);
-                 if (!ptid_equal (new_thread, null_ptid)
-                     && (!in_thread_list (new_thread)
-                         || is_exited (new_thread)))
+                 if (!ptid_equal (new_thread, null_ptid))
                    {
-                     /* When connected to a multi-process aware stub,
-                        "info threads" may show up threads of
-                        inferiors we didn't know about yet.  Add them
-                        now, and before adding any of its child
-                        threads, so notifications are emitted in a
-                        sensible order.  */
-                     if (!in_inferior_list (ptid_get_pid (new_thread)))
-                       add_inferior (ptid_get_pid (new_thread));
-
-                     add_thread (new_thread);
-
                      /* In non-stop mode, we assume new found threads
-                        are running until we proven otherwise with a
+                        are running until proven otherwise with a
                         stop reply.  In all-stop, we can only get
                         here if all threads are stopped.  */
-                     set_executing (new_thread, non_stop ? 1 : 0);
-                     set_running (new_thread, non_stop ? 1 : 0);
+                     int running = non_stop ? 1 : 0;
+
+                     remote_notice_new_inferior (new_thread, running);
                    }
                }
              while (*bufp++ == ',');   /* comma-separated list */
@@ -2605,9 +2645,6 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
        }
       else
        {
-         if (args->extended_p)
-           target_mark_running (args->target);
-
          /* Save the reply for later.  */
          wait_status = alloca (strlen (rs->buf) + 1);
          strcpy (wait_status, rs->buf);
@@ -2628,7 +2665,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
       /* Now, if we have thread information, update inferior_ptid.  */
       inferior_ptid = remote_current_thread (inferior_ptid);
 
-      add_inferior (ptid_get_pid (inferior_ptid));
+      remote_add_inferior (ptid_get_pid (inferior_ptid));
 
       /* Always add the main thread.  */
       add_thread_silent (inferior_ptid);
@@ -3394,13 +3431,12 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
     error (_("Attaching to %s failed"),
           target_pid_to_str (pid_to_ptid (pid)));
 
-  target_mark_running (target);
   inferior_ptid = pid_to_ptid (pid);
 
   /* Now, if we have thread information, update inferior_ptid.  */
   inferior_ptid = remote_current_thread (inferior_ptid);
 
-  inf = add_inferior (pid);
+  inf = remote_add_inferior (pid);
   inf->attach_flag = 1;
 
   if (non_stop)
@@ -4508,8 +4544,6 @@ process_stop_reply (struct stop_reply *stop_reply,
   if (status->kind != TARGET_WAITKIND_EXITED
       && status->kind != TARGET_WAITKIND_SIGNALLED)
     {
-      notice_new_inferiors (ptid);
-
       /* Expedited registers.  */
       if (stop_reply->regcache)
        {
@@ -4526,6 +4560,8 @@ process_stop_reply (struct stop_reply *stop_reply,
 
       remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p;
       remote_watch_data_address = stop_reply->watch_data_address;
+
+      remote_notice_new_inferior (ptid, 0);
     }
 
   stop_reply_xfree (stop_reply);
@@ -6725,11 +6761,9 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
   /* Now, if we have thread information, update inferior_ptid.  */
   inferior_ptid = remote_current_thread (inferior_ptid);
 
-  add_inferior (ptid_get_pid (inferior_ptid));
+  remote_add_inferior (ptid_get_pid (inferior_ptid));
   add_thread_silent (inferior_ptid);
 
-  target_mark_running (&extended_remote_ops);
-
   /* Get updated offsets, if the stub uses qOffsets.  */
   get_offsets ();
 }