Fix reconnecting to a gdbserver already debugging multiple processes, I
[deliverable/binutils-gdb.git] / gdb / remote.c
index 51fa5da0c18c9934da8abb1b9252ff07cb1a612f..751769ea7fc517013a3931df7ef0452a321f61d8 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);
     }
 
@@ -7441,7 +7461,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 +7484,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 +7712,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 +7859,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;
 }
This page took 0.025991 seconds and 4 git commands to generate.