Fix reconnecting to a gdbserver already debugging multiple processes, II
[deliverable/binutils-gdb.git] / gdb / remote.c
index 539b27ebd29133f2603286ae230346526c245cfe..f017f4a719c6c1d508633ac5fdde3b7b2394016a 100644 (file)
@@ -2367,6 +2367,26 @@ remote_target::remote_add_inferior (bool fake_pid_p, int pid, int attached,
         between program/address spaces.  We simply bind the inferior
         to the program space's address space.  */
       inf = current_inferior ();
+
+      /* However, if the current inferior is already bound to a
+        process, find some other empty inferior.  */
+      if (inf->pid != 0)
+       {
+         inf = nullptr;
+         for (inferior *it : all_inferiors ())
+           if (it->pid == 0)
+             {
+               inf = it;
+               break;
+             }
+       }
+      if (inf == nullptr)
+       {
+         /* Since all inferiors were already bound to a process, add
+            a new inferior.  */
+         inf = add_inferior_with_spaces ();
+       }
+      switch_to_inferior_no_thread (inf);
       inferior_appeared (inf, pid);
     }
 
@@ -4681,8 +4701,8 @@ remote_target::start_remote (int from_tty, int extended_p)
             says should be current.  If we're reconnecting to a
             multi-threaded program, this will ideally be the thread
             that last reported an event before GDB disconnected.  */
-         inferior_ptid = get_current_thread (wait_status);
-         if (inferior_ptid == null_ptid)
+         ptid_t curr_thread = get_current_thread (wait_status);
+         if (curr_thread == null_ptid)
            {
              /* Odd... The target was able to list threads, but not
                 tell us which thread was current (no "thread"
@@ -4694,8 +4714,14 @@ remote_target::start_remote (int from_tty, int extended_p)
                                    "warning: couldn't determine remote "
                                    "current thread; picking first in list.\n");
 
-             inferior_ptid = inferior_list->thread_list->ptid;
+             for (thread_info *tp : all_non_exited_threads ())
+               {
+                 switch_to_thread (tp);
+                 break;
+               }
            }
+         else
+           switch_to_thread (find_thread_ptid (curr_thread));
        }
 
       /* init_wait_for_inferior should be called before get_offsets in order
@@ -7441,7 +7467,6 @@ Packet: '%s'\n"),
     case 'W':          /* Target exited.  */
     case 'X':
       {
-       int pid;
        ULONGEST value;
 
        /* GDB used to accept only 2 hex chars here.  Stubs should
@@ -7465,8 +7490,9 @@ Packet: '%s'\n"),
              event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
          }
 
-       /* If no process is specified, assume inferior_ptid.  */
-       pid = inferior_ptid.pid ();
+       /* If no process is specified, return null_ptid, and let the
+          caller figure out the right process to use.  */
+       int pid = 0;
        if (*p == '\0')
          ;
        else if (*p == ';')
@@ -7692,6 +7718,17 @@ remote_target::wait_ns (ptid_t ptid, struct target_waitstatus *status, int optio
     }
 }
 
+/* Return the first resumed thread.  */
+
+static ptid_t
+first_remote_resumed_thread ()
+{
+  for (thread_info *tp : all_non_exited_threads (minus_one_ptid))
+    if (tp->resumed)
+      return tp->ptid;
+  return null_ptid;
+}
+
 /* Wait until the remote machine stops, then return, storing status in
    STATUS just as `wait' would.  */
 
@@ -7828,11 +7865,19 @@ remote_target::wait_as (ptid_t ptid, target_waitstatus *status, int options)
       if (event_ptid != null_ptid)
        record_currthread (rs, event_ptid);
       else
-       event_ptid = inferior_ptid;
+       event_ptid = first_remote_resumed_thread ();
     }
   else
-    /* A process exit.  Invalidate our notion of current thread.  */
-    record_currthread (rs, minus_one_ptid);
+    {
+      /* A process exit.  Invalidate our notion of current thread.  */
+      record_currthread (rs, minus_one_ptid);
+      /* It's possible that the packet did not include a pid.  */
+      if (event_ptid == null_ptid)
+       event_ptid = first_remote_resumed_thread ();
+      /* EVENT_PTID could still be NULL_PTID.  Double-check.  */
+      if (event_ptid == null_ptid)
+       event_ptid = magic_null_ptid;
+    }
 
   return event_ptid;
 }
@@ -9843,26 +9888,6 @@ remote_target::mourn_inferior ()
 
   /* Call common code to mark the inferior as not running.  */
   generic_mourn_inferior ();
-
-  if (!have_inferiors ())
-    {
-      if (!remote_multi_process_p (rs))
-       {
-         /* Check whether the target is running now - some remote stubs
-            automatically restart after kill.  */
-         putpkt ("?");
-         getpkt (&rs->buf, 0);
-
-         if (rs->buf[0] == 'S' || rs->buf[0] == 'T')
-           {
-             /* Assume that the target has been restarted.  Set
-                inferior_ptid so that bits of core GDB realizes
-                there's something here, e.g., so that the user can
-                say "kill" again.  */
-             inferior_ptid = magic_null_ptid;
-           }
-       }
-    }
 }
 
 bool
This page took 0.026273 seconds and 4 git commands to generate.