Remove usage of find_inferior in last_thread_of_process_p
[deliverable/binutils-gdb.git] / gdb / gdbserver / server.c
index 3ab042d2965a0852fc31772685fe0d6d92228638..26c4a01c9c4e63a11bc40b352c5310cbc8fc8da1 100644 (file)
 #include "job-control.h"
 #include "environ.h"
 
+#include "common/selftest.h"
+
+#define require_running_or_return(BUF)         \
+  if (!target_running ())                      \
+    {                                          \
+      write_enn (BUF);                         \
+      return;                                  \
+    }
+
+#define require_running_or_break(BUF)          \
+  if (!target_running ())                      \
+    {                                          \
+      write_enn (BUF);                         \
+      break;                                   \
+    }
+
 /* The environment to pass to the inferior when creating it.  */
 
-struct gdb_environ *our_environ = NULL;
+static gdb_environ our_environ;
 
 /* Start the inferior using a shell.  */
 
@@ -257,10 +273,10 @@ get_exec_file (int err)
 
 /* See server.h.  */
 
-struct gdb_environ *
+gdb_environ *
 get_environ ()
 {
-  return our_environ;
+  return &our_environ;
 }
 
 static int
@@ -371,8 +387,7 @@ handle_btrace_enable_bts (struct thread_info *thread)
     return "E.Btrace already enabled.";
 
   current_btrace_conf.format = BTRACE_FORMAT_BTS;
-  thread->btrace = target_enable_btrace (thread->entry.id,
-                                        &current_btrace_conf);
+  thread->btrace = target_enable_btrace (thread->id, &current_btrace_conf);
   if (thread->btrace == NULL)
     return "E.Could not enable btrace.";
 
@@ -388,8 +403,7 @@ handle_btrace_enable_pt (struct thread_info *thread)
     return "E.Btrace already enabled.";
 
   current_btrace_conf.format = BTRACE_FORMAT_PT;
-  thread->btrace = target_enable_btrace (thread->entry.id,
-                                        &current_btrace_conf);
+  thread->btrace = target_enable_btrace (thread->id, &current_btrace_conf);
   if (thread->btrace == NULL)
     return "E.Could not enable btrace.";
 
@@ -609,7 +623,7 @@ handle_general_set (char *own_buf)
        }
 
       process = current_process ();
-      VEC_truncate (int, process->syscalls_to_catch, 0);
+      process->syscalls_to_catch.clear ();
 
       if (enabled)
        {
@@ -620,17 +634,78 @@ handle_general_set (char *own_buf)
              while (*p != '\0')
                {
                  p = decode_address_to_semicolon (&sysno, p);
-                 VEC_safe_push (int, process->syscalls_to_catch, (int) sysno);
+                 process->syscalls_to_catch.push_back (sysno);
                }
            }
          else
-           VEC_safe_push (int, process->syscalls_to_catch, ANY_SYSCALL);
+           process->syscalls_to_catch.push_back (ANY_SYSCALL);
        }
 
       write_ok (own_buf);
       return;
     }
 
+  if (strcmp (own_buf, "QEnvironmentReset") == 0)
+    {
+      our_environ = gdb_environ::from_host_environ ();
+
+      write_ok (own_buf);
+      return;
+    }
+
+  if (startswith (own_buf, "QEnvironmentHexEncoded:"))
+    {
+      const char *p = own_buf + sizeof ("QEnvironmentHexEncoded:") - 1;
+      /* The final form of the environment variable.  FINAL_VAR will
+        hold the 'VAR=VALUE' format.  */
+      std::string final_var = hex2str (p);
+      std::string var_name, var_value;
+
+      if (remote_debug)
+       {
+         debug_printf (_("[QEnvironmentHexEncoded received '%s']\n"), p);
+         debug_printf (_("[Environment variable to be set: '%s']\n"),
+                       final_var.c_str ());
+         debug_flush ();
+       }
+
+      size_t pos = final_var.find ('=');
+      if (pos == std::string::npos)
+       {
+         warning (_("Unexpected format for environment variable: '%s'"),
+                  final_var.c_str ());
+         write_enn (own_buf);
+         return;
+       }
+
+      var_name = final_var.substr (0, pos);
+      var_value = final_var.substr (pos + 1, std::string::npos);
+
+      our_environ.set (var_name.c_str (), var_value.c_str ());
+
+      write_ok (own_buf);
+      return;
+    }
+
+  if (startswith (own_buf, "QEnvironmentUnset:"))
+    {
+      const char *p = own_buf + sizeof ("QEnvironmentUnset:") - 1;
+      std::string varname = hex2str (p);
+
+      if (remote_debug)
+       {
+         debug_printf (_("[QEnvironmentUnset received '%s']\n"), p);
+         debug_printf (_("[Environment variable to be unset: '%s']\n"),
+                       varname.c_str ());
+         debug_flush ();
+       }
+
+      our_environ.unset (varname.c_str ());
+
+      write_ok (own_buf);
+      return;
+    }
+
   if (strcmp (own_buf, "QStartNoAckMode") == 0)
     {
       if (remote_debug)
@@ -767,6 +842,60 @@ handle_general_set (char *own_buf)
       return;
     }
 
+  if (startswith (own_buf, "QStartupWithShell:"))
+    {
+      const char *value = own_buf + strlen ("QStartupWithShell:");
+
+      if (strcmp (value, "1") == 0)
+       startup_with_shell = true;
+      else if (strcmp (value, "0") == 0)
+       startup_with_shell = false;
+      else
+       {
+         /* Unknown value.  */
+         fprintf (stderr, "Unknown value to startup-with-shell: %s\n",
+                  own_buf);
+         write_enn (own_buf);
+         return;
+       }
+
+      if (remote_debug)
+       debug_printf (_("[Inferior will %s started with shell]"),
+                     startup_with_shell ? "be" : "not be");
+
+      write_ok (own_buf);
+      return;
+    }
+
+  if (startswith (own_buf, "QSetWorkingDir:"))
+    {
+      const char *p = own_buf + strlen ("QSetWorkingDir:");
+
+      if (*p != '\0')
+       {
+         std::string path = hex2str (p);
+
+         set_inferior_cwd (path.c_str ());
+
+         if (remote_debug)
+           debug_printf (_("[Set the inferior's current directory to %s]\n"),
+                         path.c_str ());
+       }
+      else
+       {
+         /* An empty argument means that we should clear out any
+            previously set cwd for the inferior.  */
+         set_inferior_cwd (NULL);
+
+         if (remote_debug)
+           debug_printf (_("\
+[Unset the inferior's current directory; will use gdbserver's cwd]\n"));
+       }
+      write_ok (own_buf);
+
+      return;
+    }
+
   /* Otherwise we didn't know what packet it was.  Say we didn't
      understand it.  */
   own_buf[0] = 0;
@@ -785,12 +914,14 @@ get_features_xml (const char *annex)
      This variable is set up from the auto-generated
      init_registers_... routine for the current target.  */
 
-  if (desc->xmltarget != NULL && strcmp (annex, "target.xml") == 0)
+  if (strcmp (annex, "target.xml") == 0)
     {
-      if (*desc->xmltarget == '@')
-       return desc->xmltarget + 1;
+      const char *ret = tdesc_get_features_xml ((target_desc*) desc);
+
+      if (*ret == '@')
+       return ret + 1;
       else
-       annex = desc->xmltarget;
+       annex = ret;
     }
 
 #ifdef USE_XML
@@ -865,7 +996,7 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
   res = prepare_to_access_memory ();
   if (res == 0)
     {
-      if (set_desired_thread (1))
+      if (set_desired_thread ())
        res = read_inferior_memory (memaddr, myaddr, len);
       else
        res = 1;
@@ -892,7 +1023,7 @@ gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
       ret = prepare_to_access_memory ();
       if (ret == 0)
        {
-         if (set_desired_thread (1))
+         if (set_desired_thread ())
            ret = write_inferior_memory (memaddr, myaddr, len);
          else
            ret = EIO;
@@ -1053,12 +1184,99 @@ handle_search_memory (char *own_buf, int packet_len)
   free (pattern);
 }
 
-#define require_running(BUF)                   \
-  if (!target_running ())                      \
-    {                                          \
-      write_enn (BUF);                         \
-      return;                                  \
+/* Handle the "D" packet.  */
+
+static void
+handle_detach (char *own_buf)
+{
+  require_running_or_return (own_buf);
+
+  int pid;
+
+  if (multi_process)
+    {
+      /* skip 'D;' */
+      pid = strtol (&own_buf[2], NULL, 16);
     }
+  else
+    pid = ptid_get_pid (current_ptid);
+
+  if ((tracing && disconnected_tracing) || any_persistent_commands ())
+    {
+      struct process_info *process = find_process_pid (pid);
+
+      if (process == NULL)
+       {
+         write_enn (own_buf);
+         return;
+       }
+
+      if (tracing && disconnected_tracing)
+       fprintf (stderr,
+                "Disconnected tracing in effect, "
+                "leaving gdbserver attached to the process\n");
+
+      if (any_persistent_commands ())
+       fprintf (stderr,
+                "Persistent commands are present, "
+                "leaving gdbserver attached to the process\n");
+
+      /* Make sure we're in non-stop/async mode, so we we can both
+        wait for an async socket accept, and handle async target
+        events simultaneously.  There's also no point either in
+        having the target stop all threads, when we're going to
+        pass signals down without informing GDB.  */
+      if (!non_stop)
+       {
+         if (debug_threads)
+           debug_printf ("Forcing non-stop mode\n");
+
+         non_stop = 1;
+         start_non_stop (1);
+       }
+
+      process->gdb_detached = 1;
+
+      /* Detaching implicitly resumes all threads.  */
+      target_continue_no_signal (minus_one_ptid);
+
+      write_ok (own_buf);
+      return;
+    }
+
+  fprintf (stderr, "Detaching from process %d\n", pid);
+  stop_tracing ();
+  if (detach_inferior (pid) != 0)
+    write_enn (own_buf);
+  else
+    {
+      discard_queued_stop_replies (pid_to_ptid (pid));
+      write_ok (own_buf);
+
+      if (extended_protocol || target_running ())
+       {
+         /* There is still at least one inferior remaining or
+            we are in extended mode, so don't terminate gdbserver,
+            and instead treat this like a normal program exit.  */
+         last_status.kind = TARGET_WAITKIND_EXITED;
+         last_status.value.integer = 0;
+         last_ptid = pid_to_ptid (pid);
+
+         current_thread = NULL;
+       }
+      else
+       {
+         putpkt (own_buf);
+         remote_close ();
+
+         /* If we are attached, then we can exit.  Otherwise, we
+            need to hang around doing nothing, until the child is
+            gone.  */
+         join_inferior (pid);
+         exit (0);
+       }
+    }
+}
 
 /* Parse options to --debug-format= and "monitor set debug-format".
    ARG is the text after "--debug-format=" or "monitor set debug-format".
@@ -1236,7 +1454,7 @@ handle_qxfer_auxv (const char *annex,
 /* Handle qXfer:exec-file:read.  */
 
 static int
-handle_qxfer_exec_file (const char *const_annex,
+handle_qxfer_exec_file (const char *annex,
                        gdb_byte *readbuf, const gdb_byte *writebuf,
                        ULONGEST offset, LONGEST len)
 {
@@ -1247,7 +1465,7 @@ handle_qxfer_exec_file (const char *const_annex,
   if (the_target->pid_to_exec_file == NULL || writebuf != NULL)
     return -2;
 
-  if (const_annex[0] == '\0')
+  if (annex[0] == '\0')
     {
       if (current_thread == NULL)
        return -1;
@@ -1256,11 +1474,7 @@ handle_qxfer_exec_file (const char *const_annex,
     }
   else
     {
-      char *annex = (char *) alloca (strlen (const_annex) + 1);
-
-      strcpy (annex, const_annex);
       annex = unpack_varlen_hex (annex, &pid);
-
       if (annex[0] != '\0')
        return -1;
     }
@@ -1317,48 +1531,6 @@ handle_qxfer_features (const char *annex,
   return len;
 }
 
-/* Worker routine for handle_qxfer_libraries.
-   Add to the length pointed to by ARG a conservative estimate of the
-   length needed to transmit the file name of INF.  */
-
-static void
-accumulate_file_name_length (struct inferior_list_entry *inf, void *arg)
-{
-  struct dll_info *dll = (struct dll_info *) inf;
-  unsigned int *total_len = (unsigned int *) arg;
-
-  /* Over-estimate the necessary memory.  Assume that every character
-     in the library name must be escaped.  */
-  *total_len += 128 + 6 * strlen (dll->name);
-}
-
-/* Worker routine for handle_qxfer_libraries.
-   Emit the XML to describe the library in INF.  */
-
-static void
-emit_dll_description (struct inferior_list_entry *inf, void *arg)
-{
-  struct dll_info *dll = (struct dll_info *) inf;
-  char **p_ptr = (char **) arg;
-  char *p = *p_ptr;
-  char *name;
-
-  strcpy (p, "  <library name=\"");
-  p = p + strlen (p);
-  name = xml_escape_text (dll->name);
-  strcpy (p, name);
-  free (name);
-  p = p + strlen (p);
-  strcpy (p, "\"><segment address=\"");
-  p = p + strlen (p);
-  sprintf (p, "0x%lx", (long) dll->base_addr);
-  p = p + strlen (p);
-  strcpy (p, "\"/></library>\n");
-  p = p + strlen (p);
-
-  *p_ptr = p;
-}
-
 /* Handle qXfer:libraries:read.  */
 
 static int
@@ -1366,43 +1538,29 @@ handle_qxfer_libraries (const char *annex,
                        gdb_byte *readbuf, const gdb_byte *writebuf,
                        ULONGEST offset, LONGEST len)
 {
-  unsigned int total_len;
-  char *document, *p;
-
   if (writebuf != NULL)
     return -2;
 
   if (annex[0] != '\0' || current_thread == NULL)
     return -1;
 
-  total_len = 64;
-  for_each_inferior_with_data (&all_dlls, accumulate_file_name_length,
-                              &total_len);
-
-  document = (char *) malloc (total_len);
-  if (document == NULL)
-    return -1;
+  std::string document = "<library-list version=\"1.0\">\n";
 
-  strcpy (document, "<library-list version=\"1.0\">\n");
-  p = document + strlen (document);
+  for (const dll_info &dll : all_dlls)
+    document += string_printf
+      ("  <library name=\"%s\"><segment address=\"0x%lx\"/></library>\n",
+       dll.name.c_str (), (long) dll.base_addr);
 
-  for_each_inferior_with_data (&all_dlls, emit_dll_description, &p);
+  document += "</library-list>\n";
 
-  strcpy (p, "</library-list>\n");
-
-  total_len = strlen (document);
+  if (offset > document.length ())
+    return -1;
 
-  if (offset > total_len)
-    {
-      free (document);
-      return -1;
-    }
+  if (offset + len > document.length ())
+    len = document.length () - offset;
 
-  if (offset + len > total_len)
-    len = total_len - offset;
+  memcpy (readbuf, &document[offset], len);
 
-  memcpy (readbuf, document + offset, len);
-  free (document);
   return len;
 }
 
@@ -1492,15 +1650,17 @@ handle_qxfer_statictrace (const char *annex,
    Emit the XML to describe the thread of INF.  */
 
 static void
-handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
+handle_qxfer_threads_worker (thread_info *thread, void *arg)
 {
-  struct thread_info *thread = (struct thread_info *) inf;
   struct buffer *buffer = (struct buffer *) arg;
-  ptid_t ptid = thread_to_gdb_id (thread);
+  ptid_t ptid = ptid_of (thread);
   char ptid_s[100];
   int core = target_core_of_thread (ptid);
   char core_s[21];
   const char *name = target_thread_name (ptid);
+  int handle_len;
+  gdb_byte *handle;
+  bool handle_status = target_thread_handle (ptid, &handle, &handle_len);
 
   write_ptid (ptid_s, ptid);
 
@@ -1515,6 +1675,13 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
   if (name != NULL)
     buffer_xml_printf (buffer, " name=\"%s\"", name);
 
+  if (handle_status)
+    {
+      char *handle_s = (char *) alloca (handle_len * 2 + 1);
+      bin2hex (handle, handle_s, handle_len);
+      buffer_xml_printf (buffer, " handle=\"%s\"", handle_s);
+    }
+
   buffer_xml_printf (buffer, "/>\n");
 }
 
@@ -1975,26 +2142,25 @@ supported_btrace_packets (char *buf)
 static void
 handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 {
-  static struct inferior_list_entry *thread_ptr;
+  static std::list<thread_info *>::const_iterator thread_iter;
 
   /* Reply the current thread id.  */
   if (strcmp ("qC", own_buf) == 0 && !disable_packet_qC)
     {
-      ptid_t gdb_id;
-      require_running (own_buf);
+      ptid_t ptid;
+      require_running_or_return (own_buf);
 
-      if (!ptid_equal (general_thread, null_ptid)
-         && !ptid_equal (general_thread, minus_one_ptid))
-       gdb_id = general_thread;
+      if (general_thread != null_ptid && general_thread != minus_one_ptid)
+       ptid = general_thread;
       else
        {
-         thread_ptr = get_first_inferior (&all_threads);
-         gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
+         thread_iter = all_threads.begin ();
+         ptid = (*thread_iter)->id;
        }
 
       sprintf (own_buf, "QC");
       own_buf += 2;
-      write_ptid (own_buf, gdb_id);
+      write_ptid (own_buf, ptid);
       return;
     }
 
@@ -2050,29 +2216,25 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
     {
       if (strcmp ("qfThreadInfo", own_buf) == 0)
        {
-         ptid_t gdb_id;
-
-         require_running (own_buf);
-         thread_ptr = get_first_inferior (&all_threads);
+         require_running_or_return (own_buf);
+         thread_iter = all_threads.begin ();
 
          *own_buf++ = 'm';
-         gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
-         write_ptid (own_buf, gdb_id);
-         thread_ptr = thread_ptr->next;
+         ptid_t ptid = (*thread_iter)->id;
+         write_ptid (own_buf, ptid);
+         thread_iter++;
          return;
        }
 
       if (strcmp ("qsThreadInfo", own_buf) == 0)
        {
-         ptid_t gdb_id;
-
-         require_running (own_buf);
-         if (thread_ptr != NULL)
+         require_running_or_return (own_buf);
+         if (thread_iter != all_threads.end ())
            {
              *own_buf++ = 'm';
-             gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
-             write_ptid (own_buf, gdb_id);
-             thread_ptr = thread_ptr->next;
+             ptid_t ptid = (*thread_iter)->id;
+             write_ptid (own_buf, ptid);
+             thread_iter++;
              return;
            }
          else
@@ -2088,7 +2250,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
     {
       CORE_ADDR text, data;
 
-      require_running (own_buf);
+      require_running_or_return (own_buf);
       if (the_target->read_offsets (&text, &data))
        sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
                 (long)text, (long)data, (long)data);
@@ -2203,7 +2365,10 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
        }
 
       sprintf (own_buf,
-              "PacketSize=%x;QPassSignals+;QProgramSignals+",
+              "PacketSize=%x;QPassSignals+;QProgramSignals+;"
+              "QStartupWithShell+;QEnvironmentHexEncoded+;"
+              "QEnvironmentReset+;QEnvironmentUnset+;"
+              "QSetWorkingDir+",
               PBUFSIZ - 1);
 
       if (target_supports_catch_syscall ())
@@ -2323,7 +2488,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       int i, err;
       ptid_t ptid = null_ptid;
 
-      require_running (own_buf);
+      require_running_or_return (own_buf);
 
       for (i = 0; i < 3; i++)
        {
@@ -2383,7 +2548,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
   if (the_target->get_tib_address != NULL
       && startswith (own_buf, "qGetTIBAddr:"))
     {
-      char *annex;
+      const char *annex;
       int n;
       CORE_ADDR tlb;
       ptid_t ptid = read_ptid (own_buf + 12, &annex);
@@ -2436,7 +2601,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 
   if (startswith (own_buf, "qSearch:memory:"))
     {
-      require_running (own_buf);
+      require_running_or_return (own_buf);
       handle_search_memory (own_buf, packet_len);
       return;
     }
@@ -2449,12 +2614,11 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       if (own_buf[sizeof ("qAttached") - 1])
        {
          int pid = strtoul (own_buf + sizeof ("qAttached:") - 1, NULL, 16);
-         process = (struct process_info *)
-           find_inferior_id (&all_processes, pid_to_ptid (pid));
+         process = find_process_pid (pid);
        }
       else
        {
-         require_running (own_buf);
+         require_running_or_return (own_buf);
          process = current_process ();
        }
 
@@ -2471,12 +2635,12 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
   if (startswith (own_buf, "qCRC:"))
     {
       /* CRC check (compare-section).  */
-      char *comma;
+      const char *comma;
       ULONGEST base;
       int len;
       unsigned long long crc;
 
-      require_running (own_buf);
+      require_running_or_return (own_buf);
       comma = unpack_varlen_hex (own_buf + 5, &base);
       if (*comma++ != ',')
        {
@@ -2513,48 +2677,33 @@ static void resume (struct thread_resume *actions, size_t n);
 typedef int (visit_actioned_threads_callback_ftype)
   (const struct thread_resume *, struct thread_info *);
 
-/* Struct to pass data to visit_actioned_threads.  */
-
-struct visit_actioned_threads_data
-{
-  const struct thread_resume *actions;
-  size_t num_actions;
-  visit_actioned_threads_callback_ftype *callback;
-};
-
 /* Call CALLBACK for any thread to which ACTIONS applies to.  Returns
    true if CALLBACK returns true.  Returns false if no matching thread
    is found or CALLBACK results false.
-   Note: This function is itself a callback for find_inferior.  */
+   Note: This function is itself a callback for find_thread.  */
 
-static int
-visit_actioned_threads (struct inferior_list_entry *entry, void *datap)
+static bool
+visit_actioned_threads (thread_info *thread,
+                       const struct thread_resume *actions,
+                       size_t num_actions,
+                       visit_actioned_threads_callback_ftype *callback)
 {
-  struct visit_actioned_threads_data *data
-    = (struct visit_actioned_threads_data *) datap;
-  const struct thread_resume *actions = data->actions;
-  size_t num_actions = data->num_actions;
-  visit_actioned_threads_callback_ftype *callback = data->callback;
-  size_t i;
-
-  for (i = 0; i < num_actions; i++)
+  for (size_t i = 0; i < num_actions; i++)
     {
       const struct thread_resume *action = &actions[i];
 
       if (ptid_equal (action->thread, minus_one_ptid)
-         || ptid_equal (action->thread, entry->id)
+         || ptid_equal (action->thread, thread->id)
          || ((ptid_get_pid (action->thread)
-              == ptid_get_pid (entry->id))
+              == thread->id.pid ())
              && ptid_get_lwp (action->thread) == -1))
        {
-         struct thread_info *thread = (struct thread_info *) entry;
-
          if ((*callback) (action, thread))
-           return 1;
+           return true;
        }
     }
 
-  return 0;
+  return false;
 }
 
 /* Callback for visit_actioned_threads.  If the thread has a pending
@@ -2569,7 +2718,7 @@ handle_pending_status (const struct thread_resume *resumption,
       thread->status_pending_p = 0;
 
       last_status = thread->last_status;
-      last_ptid = thread->entry.id;
+      last_ptid = thread->id;
       prepare_resume_reply (own_buf, last_ptid, &last_status);
       return 1;
     }
@@ -2580,7 +2729,7 @@ handle_pending_status (const struct thread_resume *resumption,
 static void
 handle_v_cont (char *own_buf)
 {
-  char *p, *q;
+  const char *p;
   int n = 0, i = 0;
   struct thread_resume *resume_info;
   struct thread_resume default_action { null_ptid };
@@ -2619,8 +2768,8 @@ handle_v_cont (char *own_buf)
 
       if (p[0] == 'S' || p[0] == 'C')
        {
-         int sig;
-         sig = strtol (p + 1, &q, 16);
+         char *q;
+         int sig = strtol (p + 1, &q, 16);
          if (p == q)
            goto err;
          p = q;
@@ -2657,6 +2806,7 @@ handle_v_cont (char *own_buf)
        }
       else if (p[0] == ':')
        {
+         const char *q;
          ptid_t ptid = read_ptid (p + 1, &q);
 
          if (p == q)
@@ -2695,12 +2845,14 @@ resume (struct thread_resume *actions, size_t num_actions)
         one with a pending status to report.  If so, skip actually
         resuming/stopping and report the pending event
         immediately.  */
-      struct visit_actioned_threads_data data;
 
-      data.actions = actions;
-      data.num_actions = num_actions;
-      data.callback = handle_pending_status;
-      if (find_inferior (&all_threads, visit_actioned_threads, &data) != NULL)
+      thread_info *thread_with_status = find_thread ([&] (thread_info *thread)
+       {
+         return visit_actioned_threads (thread, actions, num_actions,
+                                        handle_pending_status);
+       });
+
+      if (thread_with_status != NULL)
        return;
 
       enable_async_io ();
@@ -3067,18 +3219,16 @@ myresume (char *own_buf, int step, int sig)
 /* Callback for for_each_inferior.  Make a new stop reply for each
    stopped thread.  */
 
-static int
-queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
+static void
+queue_stop_reply_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   /* For now, assume targets that don't have this callback also don't
      manage the thread's last_status field.  */
   if (the_target->thread_stopped == NULL)
     {
       struct vstop_notif *new_notif = XNEW (struct vstop_notif);
 
-      new_notif->ptid = entry->id;
+      new_notif->ptid = thread->id;
       new_notif->status = thread->last_status;
       /* Pass the last stop reply back to GDB, but don't notify
         yet.  */
@@ -3091,25 +3241,21 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
        {
          if (debug_threads)
            {
-             char *status_string
+             std::string status_string
                = target_waitstatus_to_string (&thread->last_status);
 
              debug_printf ("Reporting thread %s as already stopped with %s\n",
-                           target_pid_to_str (entry->id),
-                           status_string);
-
-             xfree (status_string);
+                           target_pid_to_str (thread->id),
+                           status_string.c_str ());
            }
 
          gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE);
 
          /* Pass the last stop reply back to GDB, but don't notify
             yet.  */
-         queue_stop_reply (entry->id, &thread->last_status);
+         queue_stop_reply (thread->id, &thread->last_status);
        }
     }
-
-  return 0;
 }
 
 /* Set this inferior threads's state as "want-stopped".  We won't
@@ -3117,10 +3263,8 @@ queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
    it.  */
 
 static void
-gdb_wants_thread_stopped (struct inferior_list_entry *entry)
+gdb_wants_thread_stopped (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   thread->last_resume_kind = resume_stop;
 
   if (thread->last_status.kind == TARGET_WAITKIND_IGNORE)
@@ -3140,24 +3284,12 @@ gdb_wants_all_threads_stopped (void)
   for_each_inferior (&all_threads, gdb_wants_thread_stopped);
 }
 
-/* Clear the gdb_detached flag of every process.  */
-
-static void
-gdb_reattached_process (struct inferior_list_entry *entry)
-{
-  struct process_info *process = (struct process_info *) entry;
-
-  process->gdb_detached = 0;
-}
-
 /* Callback for for_each_inferior.  Clear the thread's pending status
    flag.  */
 
 static void
-clear_pending_status_callback (struct inferior_list_entry *entry)
+clear_pending_status_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   thread->status_pending_p = 0;
 }
 
@@ -3165,10 +3297,8 @@ clear_pending_status_callback (struct inferior_list_entry *entry)
    interesting event, mark it as having a pending event.  */
 
 static void
-set_pending_status_callback (struct inferior_list_entry *entry)
+set_pending_status_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
       || (thread->last_status.value.sig != GDB_SIGNAL_0
          /* A breakpoint, watchpoint or finished step from a previous
@@ -3181,24 +3311,15 @@ set_pending_status_callback (struct inferior_list_entry *entry)
     thread->status_pending_p = 1;
 }
 
-/* Callback for find_inferior.  Return true if ENTRY (a thread) has a
-   pending status to report to GDB.  */
-
-static int
-find_status_pending_thread_callback (struct inferior_list_entry *entry, void *data)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-
-  return thread->status_pending_p;
-}
-
 /* Status handler for the '?' packet.  */
 
 static void
 handle_status (char *own_buf)
 {
   /* GDB is connected, don't forward events to the target anymore.  */
-  for_each_inferior (&all_processes, gdb_reattached_process);
+  for_each_process ([] (process_info *process) {
+    process->gdb_detached = 0;
+  });
 
   /* In non-stop mode, we must send a stop reply for each stopped
      thread.  In all-stop mode, just send one for the first stopped
@@ -3206,7 +3327,7 @@ handle_status (char *own_buf)
 
   if (non_stop)
     {
-      find_inferior (&all_threads, queue_stop_reply_callback, NULL);
+      for_each_thread (queue_stop_reply_callback);
 
       /* The first is sent immediatly.  OK is sent if there is no
         stopped thread, which is the same handling of the vStopped
@@ -3215,7 +3336,7 @@ handle_status (char *own_buf)
     }
   else
     {
-      struct inferior_list_entry *thread = NULL;
+      thread_info *thread = NULL;
 
       pause_all (0);
       stabilize_threads ();
@@ -3234,18 +3355,20 @@ handle_status (char *own_buf)
       if (last_status.kind != TARGET_WAITKIND_IGNORE
          && last_status.kind != TARGET_WAITKIND_EXITED
          && last_status.kind != TARGET_WAITKIND_SIGNALLED)
-       thread = find_inferior_id (&all_threads, last_ptid);
+       thread = find_thread_ptid (last_ptid);
 
       /* If the last event thread is not found for some reason, look
         for some other thread that might have an event to report.  */
       if (thread == NULL)
-       thread = find_inferior (&all_threads,
-                               find_status_pending_thread_callback, NULL);
+       thread = find_thread ([] (thread_info *thread)
+         {
+           return thread->status_pending_p;
+         });
 
       /* If we're still out of luck, simply pick the first thread in
         the thread list.  */
       if (thread == NULL)
-       thread = get_first_inferior (&all_threads);
+       thread = get_first_thread ();
 
       if (thread != NULL)
        {
@@ -3258,10 +3381,10 @@ handle_status (char *own_buf)
          /* GDB assumes the current thread is the thread we're
             reporting the status for.  */
          general_thread = thread->id;
-         set_desired_thread (1);
+         set_desired_thread ();
 
          gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
-         prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status);
+         prepare_resume_reply (own_buf, tp->id, &tp->last_status);
        }
       else
        strcpy (own_buf, "W00");
@@ -3309,6 +3432,13 @@ gdbserver_usage (FILE *stream)
           "  --no-disable-randomization\n"
           "                        Don't disable address space randomization when\n"
           "                        starting PROG.\n"
+          "  --startup-with-shell\n"
+          "                        Start PROG using a shell.  I.e., execs a shell that\n"
+          "                        then execs PROG.  (default)\n"
+          "  --no-startup-with-shell\n"
+          "                        Exec PROG directly instead of using a shell.\n"
+          "                        Disables argument globbing and variable substitution\n"
+          "                        on UNIX-like systems.\n"
           "\n"
           "Debug options:\n"
           "\n"
@@ -3344,85 +3474,15 @@ gdbserver_show_disableable (FILE *stream)
           "  threads     \tAll of the above\n");
 }
 
-
-#undef require_running
-#define require_running(BUF)                   \
-  if (!target_running ())                      \
-    {                                          \
-      write_enn (BUF);                         \
-      break;                                   \
-    }
-
-static int
-first_thread_of (struct inferior_list_entry *entry, void *args)
-{
-  int pid = * (int *) args;
-
-  if (ptid_get_pid (entry->id) == pid)
-    return 1;
-
-  return 0;
-}
-
 static void
-kill_inferior_callback (struct inferior_list_entry *entry)
+kill_inferior_callback (process_info *process)
 {
-  struct process_info *process = (struct process_info *) entry;
-  int pid = ptid_get_pid (process->entry.id);
+  int pid = process->pid;
 
   kill_inferior (pid);
   discard_queued_stop_replies (pid_to_ptid (pid));
 }
 
-/* Callback for for_each_inferior to detach or kill the inferior,
-   depending on whether we attached to it or not.
-   We inform the user whether we're detaching or killing the process
-   as this is only called when gdbserver is about to exit.  */
-
-static void
-detach_or_kill_inferior_callback (struct inferior_list_entry *entry)
-{
-  struct process_info *process = (struct process_info *) entry;
-  int pid = ptid_get_pid (process->entry.id);
-
-  if (process->attached)
-    detach_inferior (pid);
-  else
-    kill_inferior (pid);
-
-  discard_queued_stop_replies (pid_to_ptid (pid));
-}
-
-/* for_each_inferior callback for detach_or_kill_for_exit to print
-   the pids of started inferiors.  */
-
-static void
-print_started_pid (struct inferior_list_entry *entry)
-{
-  struct process_info *process = (struct process_info *) entry;
-
-  if (! process->attached)
-    {
-      int pid = ptid_get_pid (process->entry.id);
-      fprintf (stderr, " %d", pid);
-    }
-}
-
-/* for_each_inferior callback for detach_or_kill_for_exit to print
-   the pids of attached inferiors.  */
-
-static void
-print_attached_pid (struct inferior_list_entry *entry)
-{
-  struct process_info *process = (struct process_info *) entry;
-
-  if (process->attached)
-    {
-      int pid = ptid_get_pid (process->entry.id);
-      fprintf (stderr, " %d", pid);
-    }
-}
-
 /* Call this when exiting gdbserver with possible inferiors that need
    to be killed or detached from.  */
 
@@ -3437,19 +3497,37 @@ detach_or_kill_for_exit (void)
   if (have_started_inferiors_p ())
     {
       fprintf (stderr, "Killing process(es):");
-      for_each_inferior (&all_processes, print_started_pid);
+
+      for_each_process ([] (process_info *process) {
+       if (!process->attached)
+         fprintf (stderr, " %d", process->pid);
+      });
+
       fprintf (stderr, "\n");
     }
   if (have_attached_inferiors_p ())
     {
       fprintf (stderr, "Detaching process(es):");
-      for_each_inferior (&all_processes, print_attached_pid);
+
+      for_each_process ([] (process_info *process) {
+       if (process->attached)
+         fprintf (stderr, " %d", process->pid);
+      });
+
       fprintf (stderr, "\n");
     }
 
   /* Now we can kill or detach the inferiors.  */
+  for_each_process ([] (process_info *process) {
+    int pid = process->pid;
 
-  for_each_inferior (&all_processes, detach_or_kill_inferior_callback);
+    if (process->attached)
+      detach_inferior (pid);
+    else
+      kill_inferior (pid);
+
+    discard_queued_stop_replies (pid_to_ptid (pid));
+  });
 }
 
 /* Value that will be passed to exit(3) when gdbserver exits.  */
@@ -3489,6 +3567,8 @@ captured_main (int argc, char *argv[])
   volatile int multi_mode = 0;
   volatile int attach = 0;
   int was_running;
+  bool selftest = false;
+  const char *selftest_filter = NULL;
 
   while (*next_arg != NULL && **next_arg == '-')
     {
@@ -3601,8 +3681,19 @@ captured_main (int argc, char *argv[])
        disable_randomization = 1;
       else if (strcmp (*next_arg, "--no-disable-randomization") == 0)
        disable_randomization = 0;
+      else if (strcmp (*next_arg, "--startup-with-shell") == 0)
+       startup_with_shell = true;
+      else if (strcmp (*next_arg, "--no-startup-with-shell") == 0)
+       startup_with_shell = false;
       else if (strcmp (*next_arg, "--once") == 0)
        run_once = 1;
+      else if (strcmp (*next_arg, "--selftest") == 0)
+       selftest = true;
+      else if (startswith (*next_arg, "--selftest="))
+       {
+         selftest = true;
+         selftest_filter = *next_arg + strlen ("--selftest=");
+       }
       else
        {
          fprintf (stderr, "Unknown argument: %s\n", *next_arg);
@@ -3618,7 +3709,8 @@ captured_main (int argc, char *argv[])
       port = *next_arg;
       next_arg++;
     }
-  if (port == NULL || (!attach && !multi_mode && *next_arg == NULL))
+  if ((port == NULL || (!attach && !multi_mode && *next_arg == NULL))
+       && !selftest)
     {
       gdbserver_usage (stderr);
       exit (1);
@@ -3634,7 +3726,8 @@ captured_main (int argc, char *argv[])
      starting the inferior.  Inferiors created in this scenario have
      stdin,stdout redirected.  So do this here before we call
      start_inferior.  */
-  remote_prepare (port);
+  if (port != NULL)
+    remote_prepare (port);
 
   bad_attach = 0;
   pid = 0;
@@ -3662,8 +3755,7 @@ captured_main (int argc, char *argv[])
     }
 
   /* Gather information about the environment.  */
-  our_environ = make_environ ();
-  init_environ (our_environ);
+  our_environ = gdb_environ::from_host_environ ();
 
   initialize_async_io ();
   initialize_low ();
@@ -3676,6 +3768,12 @@ captured_main (int argc, char *argv[])
   own_buf = (char *) xmalloc (PBUFSIZ + 1);
   mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
 
+  if (selftest)
+    {
+      selftests::run_tests (selftest_filter);
+      throw_quit ("Quit");
+    }
+
   if (pid == 0 && *next_arg != NULL)
     {
       int i, n;
@@ -3852,9 +3950,9 @@ main (int argc, char *argv[])
    after the last processed option.  */
 
 static void
-process_point_options (struct gdb_breakpoint *bp, char **packet)
+process_point_options (struct gdb_breakpoint *bp, const char **packet)
 {
-  char *dataptr = *packet;
+  const char *dataptr = *packet;
   int persist;
 
   /* Check if data has the correct format.  */
@@ -3905,13 +4003,10 @@ process_point_options (struct gdb_breakpoint *bp, char **packet)
 static int
 process_serial_event (void)
 {
-  char ch;
-  int i = 0;
   int signal;
   unsigned int len;
   int res;
   CORE_ADDR mem_addr;
-  int pid;
   unsigned char sig;
   int packet_len;
   int new_packet_len = -1;
@@ -3928,8 +4023,7 @@ process_serial_event (void)
     }
   response_needed = 1;
 
-  i = 0;
-  ch = own_buf[i++];
+  char ch = own_buf[0];
   switch (ch)
     {
     case 'q':
@@ -3939,91 +4033,7 @@ process_serial_event (void)
       handle_general_set (own_buf);
       break;
     case 'D':
-      require_running (own_buf);
-
-      if (multi_process)
-       {
-         i++; /* skip ';' */
-         pid = strtol (&own_buf[i], NULL, 16);
-       }
-      else
-       pid = ptid_get_pid (current_ptid);
-
-      if ((tracing && disconnected_tracing) || any_persistent_commands ())
-       {
-         struct process_info *process = find_process_pid (pid);
-
-         if (process == NULL)
-           {
-             write_enn (own_buf);
-             break;
-           }
-
-         if (tracing && disconnected_tracing)
-           fprintf (stderr,
-                    "Disconnected tracing in effect, "
-                    "leaving gdbserver attached to the process\n");
-
-         if (any_persistent_commands ())
-           fprintf (stderr,
-                    "Persistent commands are present, "
-                    "leaving gdbserver attached to the process\n");
-
-         /* Make sure we're in non-stop/async mode, so we we can both
-            wait for an async socket accept, and handle async target
-            events simultaneously.  There's also no point either in
-            having the target stop all threads, when we're going to
-            pass signals down without informing GDB.  */
-         if (!non_stop)
-           {
-             if (debug_threads)
-               debug_printf ("Forcing non-stop mode\n");
-
-             non_stop = 1;
-             start_non_stop (1);
-           }
-
-         process->gdb_detached = 1;
-
-         /* Detaching implicitly resumes all threads.  */
-         target_continue_no_signal (minus_one_ptid);
-
-         write_ok (own_buf);
-         break; /* from switch/case */
-       }
-
-      fprintf (stderr, "Detaching from process %d\n", pid);
-      stop_tracing ();
-      if (detach_inferior (pid) != 0)
-       write_enn (own_buf);
-      else
-       {
-         discard_queued_stop_replies (pid_to_ptid (pid));
-         write_ok (own_buf);
-
-         if (extended_protocol || target_running ())
-           {
-             /* There is still at least one inferior remaining or
-                we are in extended mode, so don't terminate gdbserver,
-                and instead treat this like a normal program exit.  */
-             last_status.kind = TARGET_WAITKIND_EXITED;
-             last_status.value.integer = 0;
-             last_ptid = pid_to_ptid (pid);
-
-             current_thread = NULL;
-           }
-         else
-           {
-             putpkt (own_buf);
-             remote_close ();
-
-             /* If we are attached, then we can exit.  Otherwise, we
-                need to hang around doing nothing, until the child is
-                gone.  */
-             join_inferior (pid);
-             exit (0);
-           }
-       }
+      handle_detach (own_buf);
       break;
     case '!':
       extended_protocol = 1;
@@ -4035,38 +4045,29 @@ process_serial_event (void)
     case 'H':
       if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
        {
-         ptid_t gdb_id, thread_id;
-         int pid;
-
-         require_running (own_buf);
+         require_running_or_break (own_buf);
 
-         gdb_id = read_ptid (&own_buf[2], NULL);
+         ptid_t thread_id = read_ptid (&own_buf[2], NULL);
 
-         pid = ptid_get_pid (gdb_id);
-
-         if (ptid_equal (gdb_id, null_ptid)
-             || ptid_equal (gdb_id, minus_one_ptid))
+         if (thread_id == null_ptid || thread_id == minus_one_ptid)
            thread_id = null_ptid;
-         else if (pid != 0
-                  && ptid_equal (pid_to_ptid (pid),
-                                 gdb_id))
+         else if (thread_id.is_pid ())
            {
-             struct thread_info *thread =
-               (struct thread_info *) find_inferior (&all_threads,
-                                                     first_thread_of,
-                                                     &pid);
-             if (!thread)
+             /* The ptid represents a pid.  */
+             thread_info *thread = find_any_thread_of_pid (thread_id.pid ());
+
+             if (thread == NULL)
                {
                  write_enn (own_buf);
                  break;
                }
 
-             thread_id = thread->entry.id;
+             thread_id = thread->id;
            }
          else
            {
-             thread_id = gdb_id_to_thread_id (gdb_id);
-             if (ptid_equal (thread_id, null_ptid))
+             /* The ptid represents a lwp/tid.  */
+             if (find_thread_ptid (thread_id) == NULL)
                {
                  write_enn (own_buf);
                  break;
@@ -4080,16 +4081,14 @@ process_serial_event (void)
                  /* GDB is telling us to choose any thread.  Check if
                     the currently selected thread is still valid. If
                     it is not, select the first available.  */
-                 struct thread_info *thread =
-                   (struct thread_info *) find_inferior_id (&all_threads,
-                                                            general_thread);
+                 thread_info *thread = find_thread_ptid (general_thread);
                  if (thread == NULL)
                    thread = get_first_thread ();
-                 thread_id = thread->entry.id;
+                 thread_id = thread->id;
                }
 
              general_thread = thread_id;
-             set_desired_thread (1);
+             set_desired_thread ();
              gdb_assert (current_thread != NULL);
            }
          else if (own_buf[1] == 'c')
@@ -4105,7 +4104,7 @@ process_serial_event (void)
        }
       break;
     case 'g':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       if (current_traceframe >= 0)
        {
          struct regcache *regcache
@@ -4122,7 +4121,7 @@ process_serial_event (void)
        {
          struct regcache *regcache;
 
-         if (!set_desired_thread (1))
+         if (!set_desired_thread ())
            write_enn (own_buf);
          else
            {
@@ -4132,14 +4131,14 @@ process_serial_event (void)
        }
       break;
     case 'G':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       if (current_traceframe >= 0)
        write_enn (own_buf);
       else
        {
          struct regcache *regcache;
 
-         if (!set_desired_thread (1))
+         if (!set_desired_thread ())
            write_enn (own_buf);
          else
            {
@@ -4150,7 +4149,7 @@ process_serial_event (void)
        }
       break;
     case 'm':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       decode_m_packet (&own_buf[1], &mem_addr, &len);
       res = gdb_read_memory (mem_addr, mem_buf, len);
       if (res < 0)
@@ -4159,7 +4158,7 @@ process_serial_event (void)
        bin2hex (mem_buf, own_buf, res);
       break;
     case 'M':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
       if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
        write_ok (own_buf);
@@ -4167,7 +4166,7 @@ process_serial_event (void)
        write_enn (own_buf);
       break;
     case 'X':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       if (decode_X_packet (&own_buf[1], packet_len - 1,
                           &mem_addr, &len, &mem_buf) < 0
          || gdb_write_memory (mem_addr, mem_buf, len) != 0)
@@ -4176,7 +4175,7 @@ process_serial_event (void)
        write_ok (own_buf);
       break;
     case 'C':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       hex2bin (own_buf + 1, &sig, 1);
       if (gdb_signal_to_host_p ((enum gdb_signal) sig))
        signal = gdb_signal_to_host ((enum gdb_signal) sig);
@@ -4185,7 +4184,7 @@ process_serial_event (void)
       myresume (own_buf, 0, signal);
       break;
     case 'S':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       hex2bin (own_buf + 1, &sig, 1);
       if (gdb_signal_to_host_p ((enum gdb_signal) sig))
        signal = gdb_signal_to_host ((enum gdb_signal) sig);
@@ -4194,12 +4193,12 @@ process_serial_event (void)
       myresume (own_buf, 1, signal);
       break;
     case 'c':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       signal = 0;
       myresume (own_buf, 0, signal);
       break;
     case 's':
-      require_running (own_buf);
+      require_running_or_break (own_buf);
       signal = 0;
       myresume (own_buf, 1, signal);
       break;
@@ -4213,7 +4212,7 @@ process_serial_event (void)
        char type = own_buf[1];
        int res;
        const int insert = ch == 'Z';
-       char *p = &own_buf[3];
+       const char *p = &own_buf[3];
 
        p = unpack_varlen_hex (p, &addr);
        kind = strtol (p + 1, &dataptr, 16);
@@ -4233,7 +4232,8 @@ process_serial_event (void)
                   is telling us to drop that list and use this one
                   instead.  */
                clear_breakpoint_conditions_and_commands (bp);
-               process_point_options (bp, &dataptr);
+               const char *options = dataptr;
+               process_point_options (bp, &options);
              }
          }
        else
@@ -4256,7 +4256,8 @@ process_serial_event (void)
        return 0;
 
       fprintf (stderr, "Killing all inferiors\n");
-      for_each_inferior (&all_processes, kill_inferior_callback);
+
+      for_each_process (kill_inferior_callback);
 
       /* When using the extended protocol, we wait with no program
         running.  The traditional protocol will exit instead.  */
@@ -4271,13 +4272,10 @@ process_serial_event (void)
 
     case 'T':
       {
-       ptid_t gdb_id, thread_id;
-
-       require_running (own_buf);
+       require_running_or_break (own_buf);
 
-       gdb_id = read_ptid (&own_buf[1], NULL);
-       thread_id = gdb_id_to_thread_id (gdb_id);
-       if (ptid_equal (thread_id, null_ptid))
+       ptid_t thread_id = read_ptid (&own_buf[1], NULL);
+       if (find_thread_ptid (thread_id) == NULL)
          {
            write_enn (own_buf);
            break;
@@ -4297,8 +4295,8 @@ process_serial_event (void)
       if (extended_protocol)
        {
          if (target_running ())
-           for_each_inferior (&all_processes,
-                              kill_inferior_callback);
+           for_each_process (kill_inferior_callback);
+
          fprintf (stderr, "GDBserver restarting\n");
 
          /* Wait till we are at 1st instruction in prog.  */
@@ -4373,7 +4371,7 @@ handle_serial_event (int err, gdb_client_data client_data)
 
   /* Be sure to not change the selected thread behind GDB's back.
      Important in the non-stop mode asynchronous protocol.  */
-  set_desired_thread (1);
+  set_desired_thread ();
 
   return 0;
 }
@@ -4468,7 +4466,18 @@ handle_target_event (int err, gdb_client_data client_data)
 
   /* Be sure to not change the selected thread behind GDB's back.
      Important in the non-stop mode asynchronous protocol.  */
-  set_desired_thread (1);
+  set_desired_thread ();
 
   return 0;
 }
+
+#if GDB_SELF_TEST
+namespace selftests
+{
+
+void
+reset ()
+{}
+
+} // namespace selftests
+#endif /* GDB_SELF_TEST */
This page took 0.043516 seconds and 4 git commands to generate.