Add parameter to allow enabling/disabling selftests via configure
[deliverable/binutils-gdb.git] / gdb / gdbserver / server.c
index f0dac9569af7660662455aad9b9393a55539d654..4ec3548d64444ac11e5417f4d7b40acb6dcfe27d 100644 (file)
@@ -1,5 +1,5 @@
 /* Main code for remote server for GDB.
-   Copyright (C) 1989-2017 Free Software Foundation, Inc.
+   Copyright (C) 1989-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -39,6 +39,8 @@
 #include "common-inferior.h"
 #include "job-control.h"
 #include "environ.h"
+#include "filenames.h"
+#include "pathstuff.h"
 
 #include "common/selftest.h"
 
       break;                                   \
     }
 
+/* String containing the current directory (what getwd would return).  */
+
+char *current_directory;
+
 /* The environment to pass to the inferior when creating it.  */
 
 static gdb_environ our_environ;
@@ -66,17 +72,6 @@ static gdb_environ our_environ;
 
 int startup_with_shell = 1;
 
-/* The thread set with an `Hc' packet.  `Hc' is deprecated in favor of
-   `vCont'.  Note the multi-process extensions made `vCont' a
-   requirement, so `Hc pPID.TID' is pretty much undefined.  So
-   CONT_THREAD can be null_ptid for no `Hc' thread, minus_one_ptid for
-   resuming all threads of the process (again, `Hc' isn't used for
-   multi-process), or a specific thread ptid_t.  */
-ptid_t cont_thread;
-
-/* The thread set with an `Hg' packet.  */
-ptid_t general_thread;
-
 int server_waiting;
 
 static int extended_protocol;
@@ -86,36 +81,43 @@ static int exit_requested;
 /* --once: Exit after the first connection has closed.  */
 int run_once;
 
-int multi_process;
-int report_fork_events;
-int report_vfork_events;
-int report_exec_events;
-int report_thread_events;
-
 /* Whether to report TARGET_WAITKING_NO_RESUMED events.  */
 static int report_no_resumed;
 
 int non_stop;
-int swbreak_feature;
-int hwbreak_feature;
 
-/* True if the "vContSupported" feature is active.  In that case, GDB
-   wants us to report whether single step is supported in the reply to
-   "vCont?" packet.  */
-static int vCont_supported;
+static struct {
+  /* Set the PROGRAM_PATH.  Here we adjust the path of the provided
+     binary if needed.  */
+  void set (gdb::unique_xmalloc_ptr<char> &&path)
+  {
+    m_path = std::move (path);
+
+    /* Make sure we're using the absolute path of the inferior when
+       creating it.  */
+    if (!contains_dir_separator (m_path.get ()))
+      {
+       int reg_file_errno;
+
+       /* Check if the file is in our CWD.  If it is, then we prefix
+          its name with CURRENT_DIRECTORY.  Otherwise, we leave the
+          name as-is because we'll try searching for it in $PATH.  */
+       if (is_regular_file (m_path.get (), &reg_file_errno))
+         m_path = gdb_abspath (m_path.get ());
+      }
+  }
 
-/* Whether we should attempt to disable the operating system's address
-   space randomization feature before starting an inferior.  */
-int disable_randomization = 1;
+  /* Return the PROGRAM_PATH.  */
+  char *get ()
+  { return m_path.get (); }
 
-static char *program_name = NULL;
+private:
+  /* The program name, adjusted if needed.  */
+  gdb::unique_xmalloc_ptr<char> m_path;
+} program_path;
 static std::vector<char *> program_args;
 static std::string wrapper_argv;
 
-int pass_signals[GDB_SIGNAL_LAST];
-int program_signals[GDB_SIGNAL_LAST];
-int program_signals_p;
-
 /* The PID of the originally created or attached inferior.  Used to
    send signals to the process when GDB sends us an asynchronous interrupt
    (user hitting Control-C in the client), and to wait for the child to exit
@@ -131,11 +133,6 @@ int disable_packet_Tthread;
 int disable_packet_qC;
 int disable_packet_qfThreadInfo;
 
-/* Last status reported to GDB.  */
-struct target_waitstatus last_status;
-ptid_t last_ptid;
-
-char *own_buf;
 static unsigned char *mem_buf;
 
 /* A sub-class of 'struct notif_event' for stop, holding information
@@ -159,6 +156,18 @@ static struct btrace_config current_btrace_conf;
 
 DEFINE_QUEUE_P (notif_event_p);
 
+/* The client remote protocol state. */
+
+static client_state g_client_state;
+
+client_state &
+get_client_state ()
+{
+  client_state &cs = g_client_state;
+  return cs;
+}
+
+
 /* Put a stop reply to the stop reply queue.  */
 
 static void
@@ -181,7 +190,7 @@ remove_all_on_match_ptid (QUEUE (notif_event_p) *q,
   ptid_t filter_ptid = *(ptid_t *) data;
   struct vstop_notif *vstop_event = (struct vstop_notif *) event;
 
-  if (ptid_match (vstop_event->ptid, filter_ptid))
+  if (vstop_event->ptid.matches (filter_ptid))
     {
       if (q->free_func != NULL)
        q->free_func (event);
@@ -220,13 +229,13 @@ in_queued_stop_replies_ptid (QUEUE (notif_event_p) *q,
   ptid_t filter_ptid = *(ptid_t *) data;
   struct vstop_notif *vstop_event = (struct vstop_notif *) event;
 
-  if (ptid_match (vstop_event->ptid, filter_ptid))
+  if (vstop_event->ptid.matches (filter_ptid))
     return 0;
 
   /* Don't resume fork children that GDB does not know about yet.  */
   if ((vstop_event->status.kind == TARGET_WAITKIND_FORKED
        || vstop_event->status.kind == TARGET_WAITKIND_VFORKED)
-      && ptid_match (vstop_event->status.value.related_pid, filter_ptid))
+      && vstop_event->status.value.related_pid.matches (filter_ptid))
     return 0;
 
   return 1;
@@ -265,10 +274,10 @@ get_exec_wrapper ()
 char *
 get_exec_file (int err)
 {
-  if (err && program_name == NULL)
+  if (err && program_path.get () == NULL)
     error (_("No executable file specified."));
 
-  return program_name;
+  return program_path.get ();
 }
 
 /* See server.h.  */
@@ -282,6 +291,7 @@ get_environ ()
 static int
 attach_inferior (int pid)
 {
+  client_state &cs = get_client_state ();
   /* myattach should return -1 if attaching is unsupported,
      0 if it succeeded, and call error() otherwise.  */
 
@@ -298,17 +308,17 @@ attach_inferior (int pid)
 
   if (!non_stop)
     {
-      last_ptid = mywait (pid_to_ptid (pid), &last_status, 0, 0);
+      cs.last_ptid = mywait (ptid_t (pid), &cs.last_status, 0, 0);
 
       /* GDB knows to ignore the first SIGSTOP after attaching to a running
         process using the "attach" command, but this is different; it's
         just using "target remote".  Pretend it's just starting up.  */
-      if (last_status.kind == TARGET_WAITKIND_STOPPED
-         && last_status.value.sig == GDB_SIGNAL_STOP)
-       last_status.value.sig = GDB_SIGNAL_TRAP;
+      if (cs.last_status.kind == TARGET_WAITKIND_STOPPED
+         && cs.last_status.value.sig == GDB_SIGNAL_STOP)
+       cs.last_status.value.sig = GDB_SIGNAL_TRAP;
 
       current_thread->last_resume_kind = resume_stop;
-      current_thread->last_status = last_status;
+      current_thread->last_status = cs.last_status;
     }
 
   return 0;
@@ -380,50 +390,41 @@ write_qxfer_response (char *buf, const gdb_byte *data, int len, int is_more)
 
 /* Handle btrace enabling in BTS format.  */
 
-static const char *
+static void
 handle_btrace_enable_bts (struct thread_info *thread)
 {
   if (thread->btrace != NULL)
-    return "E.Btrace already enabled.";
+    error (_("Btrace already enabled."));
 
   current_btrace_conf.format = BTRACE_FORMAT_BTS;
   thread->btrace = target_enable_btrace (thread->id, &current_btrace_conf);
-  if (thread->btrace == NULL)
-    return "E.Could not enable btrace.";
-
-  return NULL;
 }
 
 /* Handle btrace enabling in Intel Processor Trace format.  */
 
-static const char *
+static void
 handle_btrace_enable_pt (struct thread_info *thread)
 {
   if (thread->btrace != NULL)
-    return "E.Btrace already enabled.";
+    error (_("Btrace already enabled."));
 
   current_btrace_conf.format = BTRACE_FORMAT_PT;
   thread->btrace = target_enable_btrace (thread->id, &current_btrace_conf);
-  if (thread->btrace == NULL)
-    return "E.Could not enable btrace.";
-
-  return NULL;
 }
 
 /* Handle btrace disabling.  */
 
-static const char *
+static void
 handle_btrace_disable (struct thread_info *thread)
 {
 
   if (thread->btrace == NULL)
-    return "E.Branch tracing not enabled.";
+    error (_("Branch tracing not enabled."));
 
   if (target_disable_btrace (thread->btrace) != 0)
-    return "E.Could not disable branch tracing.";
+    error (_("Could not disable branch tracing."));
 
   thread->btrace = NULL;
-  return NULL;
 }
 
 /* Handle the "Qbtrace" packet.  */
@@ -431,8 +432,8 @@ handle_btrace_disable (struct thread_info *thread)
 static int
 handle_btrace_general_set (char *own_buf)
 {
+  client_state &cs = get_client_state ();
   struct thread_info *thread;
-  const char *err;
   char *op;
 
   if (!startswith (own_buf, "Qbtrace:"))
@@ -440,35 +441,38 @@ handle_btrace_general_set (char *own_buf)
 
   op = own_buf + strlen ("Qbtrace:");
 
-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (cs.general_thread == null_ptid
+      || cs.general_thread == minus_one_ptid)
     {
       strcpy (own_buf, "E.Must select a single thread.");
       return -1;
     }
 
-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs.general_thread);
   if (thread == NULL)
     {
       strcpy (own_buf, "E.No such thread.");
       return -1;
     }
 
-  err = NULL;
-
-  if (strcmp (op, "bts") == 0)
-    err = handle_btrace_enable_bts (thread);
-  else if (strcmp (op, "pt") == 0)
-    err = handle_btrace_enable_pt (thread);
-  else if (strcmp (op, "off") == 0)
-    err = handle_btrace_disable (thread);
-  else
-    err = "E.Bad Qbtrace operation. Use bts, pt, or off.";
+  TRY
+    {
+      if (strcmp (op, "bts") == 0)
+       handle_btrace_enable_bts (thread);
+      else if (strcmp (op, "pt") == 0)
+       handle_btrace_enable_pt (thread);
+      else if (strcmp (op, "off") == 0)
+       handle_btrace_disable (thread);
+      else
+       error (_("Bad Qbtrace operation.  Use bts, pt, or off."));
 
-  if (err != 0)
-    strcpy (own_buf, err);
-  else
-    write_ok (own_buf);
+      write_ok (own_buf);
+    }
+  CATCH (exception, RETURN_MASK_ERROR)
+    {
+      sprintf (own_buf, "E.%s", exception.message);
+    }
+  END_CATCH
 
   return 1;
 }
@@ -478,6 +482,7 @@ handle_btrace_general_set (char *own_buf)
 static int
 handle_btrace_conf_general_set (char *own_buf)
 {
+  client_state &cs = get_client_state ();
   struct thread_info *thread;
   char *op;
 
@@ -486,14 +491,14 @@ handle_btrace_conf_general_set (char *own_buf)
 
   op = own_buf + strlen ("Qbtrace-conf:");
 
-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (cs.general_thread == null_ptid
+      || cs.general_thread == minus_one_ptid)
     {
       strcpy (own_buf, "E.Must select a single thread.");
       return -1;
     }
 
-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs.general_thread);
   if (thread == NULL)
     {
       strcpy (own_buf, "E.No such thread.");
@@ -545,6 +550,7 @@ handle_btrace_conf_general_set (char *own_buf)
 static void
 handle_general_set (char *own_buf)
 {
+  client_state &cs = get_client_state ();
   if (startswith (own_buf, "QPassSignals:"))
     {
       int numsigs = (int) GDB_SIGNAL_LAST, i;
@@ -556,7 +562,7 @@ handle_general_set (char *own_buf)
        {
          if (i == cursig)
            {
-             pass_signals[i] = 1;
+             cs.pass_signals[i] = 1;
              if (*p == '\0')
                /* Keep looping, to clear the remaining signals.  */
                cursig = -1;
@@ -564,7 +570,7 @@ handle_general_set (char *own_buf)
                p = decode_address_to_semicolon (&cursig, p);
            }
          else
-           pass_signals[i] = 0;
+           cs.pass_signals[i] = 0;
        }
       strcpy (own_buf, "OK");
       return;
@@ -576,14 +582,14 @@ handle_general_set (char *own_buf)
       const char *p = own_buf + strlen ("QProgramSignals:");
       CORE_ADDR cursig;
 
-      program_signals_p = 1;
+      cs.program_signals_p = 1;
 
       p = decode_address_to_semicolon (&cursig, p);
       for (i = 0; i < numsigs; i++)
        {
          if (i == cursig)
            {
-             program_signals[i] = 1;
+             cs.program_signals[i] = 1;
              if (*p == '\0')
                /* Keep looping, to clear the remaining signals.  */
                cursig = -1;
@@ -591,7 +597,7 @@ handle_general_set (char *own_buf)
                p = decode_address_to_semicolon (&cursig, p);
            }
          else
-           program_signals[i] = 0;
+           cs.program_signals[i] = 0;
        }
       strcpy (own_buf, "OK");
       return;
@@ -714,7 +720,7 @@ handle_general_set (char *own_buf)
          debug_flush ();
        }
 
-      noack_mode = 1;
+      cs.noack_mode = 1;
       write_ok (own_buf);
       return;
     }
@@ -762,11 +768,11 @@ handle_general_set (char *own_buf)
       ULONGEST setting;
 
       unpack_varlen_hex (packet, &setting);
-      disable_randomization = setting;
+      cs.disable_randomization = setting;
 
       if (remote_debug)
        {
-         debug_printf (disable_randomization
+         debug_printf (cs.disable_randomization
                        ? "[address space randomization disabled]\n"
                        : "[address space randomization enabled]\n");
        }
@@ -820,20 +826,17 @@ handle_general_set (char *own_buf)
        req = TRIBOOL_TRUE;
       else
        {
-         char *mode_copy = xstrdup (mode);
-
          /* We don't know what this mode is, so complain to GDB.  */
          sprintf (own_buf, "E.Unknown thread-events mode requested: %s\n",
-                  mode_copy);
-         xfree (mode_copy);
+                  mode);
          return;
        }
 
-      report_thread_events = (req == TRIBOOL_TRUE);
+      cs.report_thread_events = (req == TRIBOOL_TRUE);
 
       if (remote_debug)
        {
-         const char *req_str = report_thread_events ? "enabled" : "disabled";
+         const char *req_str = cs.report_thread_events ? "enabled" : "disabled";
 
          debug_printf ("[thread events are now %s]\n", req_str);
        }
@@ -916,7 +919,7 @@ get_features_xml (const char *annex)
 
   if (strcmp (annex, "target.xml") == 0)
     {
-      const char *ret = tdesc_get_features_xml ((target_desc*) desc);
+      const char *ret = tdesc_get_features_xml (desc);
 
       if (*ret == '@')
        return ret + 1;
@@ -974,14 +977,15 @@ monitor_show_help (void)
 static int
 gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
+  client_state &cs = get_client_state ();
   int res;
 
-  if (current_traceframe >= 0)
+  if (cs.current_traceframe >= 0)
     {
       ULONGEST nbytes;
       ULONGEST length = len;
 
-      if (traceframe_read_mem (current_traceframe,
+      if (traceframe_read_mem (cs.current_traceframe,
                               memaddr, myaddr, len, &nbytes))
        return -1;
       /* Data read from trace buffer, we're done.  */
@@ -1014,7 +1018,8 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 static int
 gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 {
-  if (current_traceframe >= 0)
+  client_state &cs = get_client_state ();
+  if (cs.current_traceframe >= 0)
     return EIO;
   else
     {
@@ -1189,34 +1194,38 @@ handle_search_memory (char *own_buf, int packet_len)
 static void
 handle_detach (char *own_buf)
 {
-  require_running_or_return (own_buf);
+  client_state &cs = get_client_state ();
 
-  int pid;
+  process_info *process;
 
-  if (multi_process)
+  if (cs.multi_process)
     {
       /* skip 'D;' */
-      pid = strtol (&own_buf[2], NULL, 16);
+      int pid = strtol (&own_buf[2], NULL, 16);
+
+      process = find_process_pid (pid);
     }
   else
-    pid = ptid_get_pid (current_ptid);
-
-  if ((tracing && disconnected_tracing) || any_persistent_commands ())
     {
-      struct process_info *process = find_process_pid (pid);
+      process = (current_thread != nullptr
+                ? get_thread_process (current_thread)
+                : nullptr);
+    }
 
-      if (process == NULL)
-       {
-         write_enn (own_buf);
-         return;
-       }
+  if (process == NULL)
+    {
+      write_enn (own_buf);
+      return;
+    }
 
+  if ((tracing && disconnected_tracing) || any_persistent_commands (process))
+    {
       if (tracing && disconnected_tracing)
        fprintf (stderr,
                 "Disconnected tracing in effect, "
                 "leaving gdbserver attached to the process\n");
 
-      if (any_persistent_commands ())
+      if (any_persistent_commands (process))
        fprintf (stderr,
                 "Persistent commands are present, "
                 "leaving gdbserver attached to the process\n");
@@ -1244,13 +1253,13 @@ handle_detach (char *own_buf)
       return;
     }
 
-  fprintf (stderr, "Detaching from process %d\n", pid);
+  fprintf (stderr, "Detaching from process %d\n", process->pid);
   stop_tracing ();
-  if (detach_inferior (pid) != 0)
+  if (detach_inferior (process) != 0)
     write_enn (own_buf);
   else
     {
-      discard_queued_stop_replies (pid_to_ptid (pid));
+      discard_queued_stop_replies (ptid_t (process->pid));
       write_ok (own_buf);
 
       if (extended_protocol || target_running ())
@@ -1258,9 +1267,9 @@ handle_detach (char *own_buf)
          /* 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);
+         cs.last_status.kind = TARGET_WAITKIND_EXITED;
+         cs.last_status.value.integer = 0;
+         cs.last_ptid = ptid_t (process->pid);
 
          current_thread = NULL;
        }
@@ -1272,7 +1281,7 @@ handle_detach (char *own_buf)
          /* If we are attached, then we can exit.  Otherwise, we
             need to hang around doing nothing, until the child is
             gone.  */
-         join_inferior (pid);
+         join_inferior (process);
          exit (0);
        }
     }
@@ -1282,8 +1291,8 @@ handle_detach (char *own_buf)
    ARG is the text after "--debug-format=" or "monitor set debug-format".
    IS_MONITOR is non-zero if we're invoked via "monitor set debug-format".
    This triggers calls to monitor_output.
-   The result is NULL if all options were parsed ok, otherwise an error
-   message which the caller must free.
+   The result is an empty string if all options were parsed ok, otherwise an
+   error message which the caller must free.
 
    N.B. These commands affect all debug format settings, they are not
    cumulative.  If a format is not specified, it is turned off.
@@ -1295,13 +1304,9 @@ handle_detach (char *own_buf)
    to gdb's "set debug foo on|off" because we also use this function to
    parse "--debug-format=foo,bar".  */
 
-static char *
+static std::string
 parse_debug_format_options (const char *arg, int is_monitor)
 {
-  VEC (char_ptr) *options;
-  int ix;
-  char *option;
-
   /* First turn all debug format options off.  */
   debug_timestamp = 0;
 
@@ -1309,23 +1314,24 @@ parse_debug_format_options (const char *arg, int is_monitor)
   while (isspace (*arg))
     ++arg;
 
-  options = delim_string_to_char_ptr_vec (arg, ',');
+  std::vector<gdb::unique_xmalloc_ptr<char>> options
+    = delim_string_to_char_ptr_vec (arg, ',');
 
-  for (ix = 0; VEC_iterate (char_ptr, options, ix, option); ++ix)
+  for (const gdb::unique_xmalloc_ptr<char> &option : options)
     {
-      if (strcmp (option, "all") == 0)
+      if (strcmp (option.get (), "all") == 0)
        {
          debug_timestamp = 1;
          if (is_monitor)
            monitor_output ("All extra debug format options enabled.\n");
        }
-      else if (strcmp (option, "none") == 0)
+      else if (strcmp (option.get (), "none") == 0)
        {
          debug_timestamp = 0;
          if (is_monitor)
            monitor_output ("All extra debug format options disabled.\n");
        }
-      else if (strcmp (option, "timestamp") == 0)
+      else if (strcmp (option.get (), "timestamp") == 0)
        {
          debug_timestamp = 1;
          if (is_monitor)
@@ -1337,17 +1343,11 @@ parse_debug_format_options (const char *arg, int is_monitor)
          continue;
        }
       else
-       {
-         char *msg = xstrprintf ("Unknown debug-format argument: \"%s\"\n",
-                                 option);
-
-         free_char_ptr_vec (options);
-         return msg;
-       }
+       return string_printf ("Unknown debug-format argument: \"%s\"\n",
+                             option.get ());
     }
 
-  free_char_ptr_vec (options);
-  return NULL;
+  return std::string ();
 }
 
 /* Handle monitor commands not handled by target-specific handlers.  */
@@ -1387,16 +1387,15 @@ handle_monitor_command (char *mon, char *own_buf)
     }
   else if (startswith (mon, "set debug-format "))
     {
-      char *error_msg
+      std::string error_msg
        = parse_debug_format_options (mon + sizeof ("set debug-format ") - 1,
                                      1);
 
-      if (error_msg != NULL)
+      if (!error_msg.empty ())
        {
-         monitor_output (error_msg);
+         monitor_output (error_msg.c_str ());
          monitor_show_help ();
          write_enn (own_buf);
-         xfree (error_msg);
        }
     }
   else if (strcmp (mon, "help") == 0)
@@ -1632,15 +1631,17 @@ handle_qxfer_statictrace (const char *annex,
                          gdb_byte *readbuf, const gdb_byte *writebuf,
                          ULONGEST offset, LONGEST len)
 {
+  client_state &cs = get_client_state ();
   ULONGEST nbytes;
 
   if (writebuf != NULL)
     return -2;
 
-  if (annex[0] != '\0' || current_thread == NULL || current_traceframe == -1)
+  if (annex[0] != '\0' || current_thread == NULL 
+      || cs.current_traceframe == -1)
     return -1;
 
-  if (traceframe_read_sdata (current_traceframe, offset,
+  if (traceframe_read_sdata (cs.current_traceframe, offset,
                             readbuf, len, &nbytes))
     return -1;
   return nbytes;
@@ -1650,9 +1651,8 @@ handle_qxfer_statictrace (const char *annex,
    Emit the XML to describe the thread of INF.  */
 
 static void
-handle_qxfer_threads_worker (thread_info *thread, void *arg)
+handle_qxfer_threads_worker (thread_info *thread, struct buffer *buffer)
 {
-  struct buffer *buffer = (struct buffer *) arg;
   ptid_t ptid = ptid_of (thread);
   char ptid_s[100];
   int core = target_core_of_thread (ptid);
@@ -1692,8 +1692,10 @@ handle_qxfer_threads_proper (struct buffer *buffer)
 {
   buffer_grow_str (buffer, "<threads>\n");
 
-  for_each_inferior_with_data (&all_threads, handle_qxfer_threads_worker,
-                              buffer);
+  for_each_thread ([&] (thread_info *thread)
+    {
+      handle_qxfer_threads_worker (thread, buffer);
+    });
 
   buffer_grow_str0 (buffer, "</threads>\n");
 }
@@ -1755,13 +1757,14 @@ handle_qxfer_traceframe_info (const char *annex,
                              gdb_byte *readbuf, const gdb_byte *writebuf,
                              ULONGEST offset, LONGEST len)
 {
+  client_state &cs = get_client_state ();
   static char *result = 0;
   static unsigned int result_length = 0;
 
   if (writebuf != NULL)
     return -2;
 
-  if (!target_running () || annex[0] != '\0' || current_traceframe == -1)
+  if (!target_running () || annex[0] != '\0' || cs.current_traceframe == -1)
     return -1;
 
   if (offset == 0)
@@ -1775,7 +1778,7 @@ handle_qxfer_traceframe_info (const char *annex,
 
       buffer_init (&buffer);
 
-      traceframe_read_info (current_traceframe, &buffer);
+      traceframe_read_info (cs.current_traceframe, &buffer);
 
       result = buffer_finish (&buffer);
       result_length = strlen (result);
@@ -1820,31 +1823,32 @@ handle_qxfer_btrace (const char *annex,
                     gdb_byte *readbuf, const gdb_byte *writebuf,
                     ULONGEST offset, LONGEST len)
 {
+  client_state &cs = get_client_state ();
   static struct buffer cache;
   struct thread_info *thread;
   enum btrace_read_type type;
   int result;
 
-  if (the_target->read_btrace == NULL || writebuf != NULL)
+  if (writebuf != NULL)
     return -2;
 
-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (cs.general_thread == null_ptid
+      || cs.general_thread == minus_one_ptid)
     {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (cs.own_buf, "E.Must select a single thread.");
       return -3;
     }
 
-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs.general_thread);
   if (thread == NULL)
     {
-      strcpy (own_buf, "E.No such thread.");
+      strcpy (cs.own_buf, "E.No such thread.");
       return -3;
     }
 
   if (thread->btrace == NULL)
     {
-      strcpy (own_buf, "E.Btrace not enabled.");
+      strcpy (cs.own_buf, "E.Btrace not enabled.");
       return -3;
     }
 
@@ -1856,7 +1860,7 @@ handle_qxfer_btrace (const char *annex,
     type = BTRACE_READ_DELTA;
   else
     {
-      strcpy (own_buf, "E.Bad annex.");
+      strcpy (cs.own_buf, "E.Bad annex.");
       return -3;
     }
 
@@ -1864,12 +1868,21 @@ handle_qxfer_btrace (const char *annex,
     {
       buffer_free (&cache);
 
-      result = target_read_btrace (thread->btrace, &cache, type);
-      if (result != 0)
+      TRY
        {
-         memcpy (own_buf, cache.buffer, cache.used_size);
-         return -3;
+         result = target_read_btrace (thread->btrace, &cache, type);
+         if (result != 0)
+           memcpy (cs.own_buf, cache.buffer, cache.used_size);
        }
+      CATCH (exception, RETURN_MASK_ERROR)
+       {
+         sprintf (cs.own_buf, "E.%s", exception.message);
+         result = -1;
+       }
+      END_CATCH
+
+      if (result != 0)
+       return -3;
     }
   else if (offset > cache.used_size)
     {
@@ -1892,33 +1905,34 @@ handle_qxfer_btrace_conf (const char *annex,
                          gdb_byte *readbuf, const gdb_byte *writebuf,
                          ULONGEST offset, LONGEST len)
 {
+  client_state &cs = get_client_state ();
   static struct buffer cache;
   struct thread_info *thread;
   int result;
 
-  if (the_target->read_btrace_conf == NULL || writebuf != NULL)
+  if (writebuf != NULL)
     return -2;
 
   if (annex[0] != '\0')
     return -1;
 
-  if (ptid_equal (general_thread, null_ptid)
-      || ptid_equal (general_thread, minus_one_ptid))
+  if (cs.general_thread == null_ptid
+      || cs.general_thread == minus_one_ptid)
     {
-      strcpy (own_buf, "E.Must select a single thread.");
+      strcpy (cs.own_buf, "E.Must select a single thread.");
       return -3;
     }
 
-  thread = find_thread_ptid (general_thread);
+  thread = find_thread_ptid (cs.general_thread);
   if (thread == NULL)
     {
-      strcpy (own_buf, "E.No such thread.");
+      strcpy (cs.own_buf, "E.No such thread.");
       return -3;
     }
 
   if (thread->btrace == NULL)
     {
-      strcpy (own_buf, "E.Btrace not enabled.");
+      strcpy (cs.own_buf, "E.Btrace not enabled.");
       return -3;
     }
 
@@ -1926,12 +1940,21 @@ handle_qxfer_btrace_conf (const char *annex,
     {
       buffer_free (&cache);
 
-      result = target_read_btrace_conf (thread->btrace, &cache);
-      if (result != 0)
+      TRY
+       {
+         result = target_read_btrace_conf (thread->btrace, &cache);
+         if (result != 0)
+           memcpy (cs.own_buf, cache.buffer, cache.used_size);
+       }
+      CATCH (exception, RETURN_MASK_ERROR)
        {
-         memcpy (own_buf, cache.buffer, cache.used_size);
-         return -3;
+         sprintf (cs.own_buf, "E.%s", exception.message);
+         result = -1;
        }
+      END_CATCH
+
+      if (result != 0)
+       return -3;
     }
   else if (offset > cache.used_size)
     {
@@ -2111,27 +2134,10 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
 static void
 supported_btrace_packets (char *buf)
 {
-  int btrace_supported = 0;
-
-  if (target_supports_btrace (BTRACE_FORMAT_BTS))
-    {
-      strcat (buf, ";Qbtrace:bts+");
-      strcat (buf, ";Qbtrace-conf:bts:size+");
-
-      btrace_supported = 1;
-    }
-
-  if (target_supports_btrace (BTRACE_FORMAT_PT))
-    {
-      strcat (buf, ";Qbtrace:pt+");
-      strcat (buf, ";Qbtrace-conf:pt:size+");
-
-      btrace_supported = 1;
-    }
-
-  if (!btrace_supported)
-    return;
-
+  strcat (buf, ";Qbtrace:bts+");
+  strcat (buf, ";Qbtrace-conf:bts:size+");
+  strcat (buf, ";Qbtrace:pt+");
+  strcat (buf, ";Qbtrace-conf:pt:size+");
   strcat (buf, ";Qbtrace:off+");
   strcat (buf, ";qXfer:btrace:read+");
   strcat (buf, ";qXfer:btrace-conf:read+");
@@ -2142,6 +2148,7 @@ supported_btrace_packets (char *buf)
 static void
 handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 {
+  client_state &cs = get_client_state ();
   static std::list<thread_info *>::const_iterator thread_iter;
 
   /* Reply the current thread id.  */
@@ -2150,8 +2157,8 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       ptid_t ptid;
       require_running_or_return (own_buf);
 
-      if (general_thread != null_ptid && general_thread != minus_one_ptid)
-       ptid = general_thread;
+      if (cs.general_thread != null_ptid && cs.general_thread != minus_one_ptid)
+       ptid = cs.general_thread;
       else
        {
          thread_iter = all_threads.begin ();
@@ -2176,7 +2183,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       if (current_thread == NULL)
        {
          current_thread
-           = find_any_thread_of_pid (ptid_get_pid (general_thread));
+           = find_any_thread_of_pid (cs.general_thread.pid ());
 
          /* Just in case, if we didn't find a thread, then bail out
             instead of crashing.  */
@@ -2296,7 +2303,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
                  /* GDB supports and wants multi-process support if
                     possible.  */
                  if (target_supports_multi_process ())
-                   multi_process = 1;
+                   cs.multi_process = 1;
                }
              else if (strcmp (p, "qRelocInsn+") == 0)
                {
@@ -2309,35 +2316,35 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
                     by a software breakpoint and for us to handle PC
                     adjustment if necessary on this target.  */
                  if (target_supports_stopped_by_sw_breakpoint ())
-                   swbreak_feature = 1;
+                   cs.swbreak_feature = 1;
                }
              else if (strcmp (p, "hwbreak+") == 0)
                {
                  /* GDB wants us to report whether a trap is caused
                     by a hardware breakpoint.  */
                  if (target_supports_stopped_by_hw_breakpoint ())
-                   hwbreak_feature = 1;
+                   cs.hwbreak_feature = 1;
                }
              else if (strcmp (p, "fork-events+") == 0)
                {
                  /* GDB supports and wants fork events if possible.  */
                  if (target_supports_fork_events ())
-                   report_fork_events = 1;
+                   cs.report_fork_events = 1;
                }
              else if (strcmp (p, "vfork-events+") == 0)
                {
                  /* GDB supports and wants vfork events if possible.  */
                  if (target_supports_vfork_events ())
-                   report_vfork_events = 1;
+                   cs.report_vfork_events = 1;
                }
              else if (strcmp (p, "exec-events+") == 0)
                {
                  /* GDB supports and wants exec events if possible.  */
                  if (target_supports_exec_events ())
-                   report_exec_events = 1;
+                   cs.report_exec_events = 1;
                }
              else if (strcmp (p, "vContSupported+") == 0)
-               vCont_supported = 1;
+               cs.vCont_supported = 1;
              else if (strcmp (p, "QThreadEvents+") == 0)
                ;
              else if (strcmp (p, "no-resumed+") == 0)
@@ -2402,7 +2409,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
         qXfer:feature:read at all, we will never be re-queried.  */
       strcat (own_buf, ";qXfer:features:read+");
 
-      if (transport_is_reliable)
+      if (cs.transport_is_reliable)
        strcat (own_buf, ";QStartNoAckMode+");
 
       if (the_target->qxfer_osdata != NULL)
@@ -2692,11 +2699,11 @@ visit_actioned_threads (thread_info *thread,
     {
       const struct thread_resume *action = &actions[i];
 
-      if (ptid_equal (action->thread, minus_one_ptid)
-         || ptid_equal (action->thread, thread->id)
-         || ((ptid_get_pid (action->thread)
+      if (action->thread == minus_one_ptid
+         || action->thread == thread->id
+         || ((action->thread.pid ()
               == thread->id.pid ())
-             && ptid_get_lwp (action->thread) == -1))
+             && action->thread.lwp () == -1))
        {
          if ((*callback) (action, thread))
            return true;
@@ -2713,13 +2720,14 @@ static int
 handle_pending_status (const struct thread_resume *resumption,
                       struct thread_info *thread)
 {
+  client_state &cs = get_client_state ();
   if (thread->status_pending_p)
     {
       thread->status_pending_p = 0;
 
-      last_status = thread->last_status;
-      last_ptid = thread->id;
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      cs.last_status = thread->last_status;
+      cs.last_ptid = thread->id;
+      prepare_resume_reply (cs.own_buf, cs.last_ptid, &cs.last_status);
       return 1;
     }
   return 0;
@@ -2839,6 +2847,7 @@ err:
 static void
 resume (struct thread_resume *actions, size_t num_actions)
 {
+  client_state &cs = get_client_state ();
   if (!non_stop)
     {
       /* Check if among the threads that GDB wants actioned, there's
@@ -2861,37 +2870,37 @@ resume (struct thread_resume *actions, size_t num_actions)
   (*the_target->resume) (actions, num_actions);
 
   if (non_stop)
-    write_ok (own_buf);
+    write_ok (cs.own_buf);
   else
     {
-      last_ptid = mywait (minus_one_ptid, &last_status, 0, 1);
+      cs.last_ptid = mywait (minus_one_ptid, &cs.last_status, 0, 1);
 
-      if (last_status.kind == TARGET_WAITKIND_NO_RESUMED
+      if (cs.last_status.kind == TARGET_WAITKIND_NO_RESUMED
          && !report_no_resumed)
        {
          /* The client does not support this stop reply.  At least
             return error.  */
-         sprintf (own_buf, "E.No unwaited-for children left.");
+         sprintf (cs.own_buf, "E.No unwaited-for children left.");
          disable_async_io ();
          return;
        }
 
-      if (last_status.kind != TARGET_WAITKIND_EXITED
-          && last_status.kind != TARGET_WAITKIND_SIGNALLED
-         && last_status.kind != TARGET_WAITKIND_NO_RESUMED)
-       current_thread->last_status = last_status;
+      if (cs.last_status.kind != TARGET_WAITKIND_EXITED
+          && cs.last_status.kind != TARGET_WAITKIND_SIGNALLED
+         && cs.last_status.kind != TARGET_WAITKIND_NO_RESUMED)
+       current_thread->last_status = cs.last_status;
 
       /* From the client's perspective, all-stop mode always stops all
         threads implicitly (and the target backend has already done
         so by now).  Tag all threads as "want-stopped", so we don't
         resume them implicitly without the client telling us to.  */
       gdb_wants_all_threads_stopped ();
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      prepare_resume_reply (cs.own_buf, cs.last_ptid, &cs.last_status);
       disable_async_io ();
 
-      if (last_status.kind == TARGET_WAITKIND_EXITED
-          || last_status.kind == TARGET_WAITKIND_SIGNALLED)
-        target_mourn_inferior (last_ptid);
+      if (cs.last_status.kind == TARGET_WAITKIND_EXITED
+          || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)
+        target_mourn_inferior (cs.last_ptid);
     }
 }
 
@@ -2899,6 +2908,7 @@ resume (struct thread_resume *actions, size_t num_actions)
 static int
 handle_v_attach (char *own_buf)
 {
+  client_state &cs = get_client_state ();
   int pid;
 
   pid = strtol (own_buf + 8, NULL, 16);
@@ -2918,7 +2928,7 @@ handle_v_attach (char *own_buf)
          write_ok (own_buf);
        }
       else
-       prepare_resume_reply (own_buf, last_ptid, &last_status);
+       prepare_resume_reply (own_buf, cs.last_ptid, &cs.last_status);
 
       return 1;
     }
@@ -2933,6 +2943,7 @@ handle_v_attach (char *own_buf)
 static int
 handle_v_run (char *own_buf)
 {
+  client_state &cs = get_client_state ();
   char *p, *next_p;
   std::vector<char *> new_argv;
   char *new_program_name = NULL;
@@ -3023,7 +3034,7 @@ handle_v_run (char *own_buf)
     {
       /* GDB didn't specify a program to run.  Use the program from the
         last run with the new argument list.  */
-      if (program_name == NULL)
+      if (program_path.get () == NULL)
        {
          write_enn (own_buf);
          free_vector_argv (new_argv);
@@ -3031,26 +3042,23 @@ handle_v_run (char *own_buf)
        }
     }
   else
-    {
-      xfree (program_name);
-      program_name = new_program_name;
-    }
+    program_path.set (gdb::unique_xmalloc_ptr<char> (new_program_name));
 
   /* Free the old argv and install the new one.  */
   free_vector_argv (program_args);
   program_args = new_argv;
 
-  create_inferior (program_name, program_args);
+  create_inferior (program_path.get (), program_args);
 
-  if (last_status.kind == TARGET_WAITKIND_STOPPED)
+  if (cs.last_status.kind == TARGET_WAITKIND_STOPPED)
     {
-      prepare_resume_reply (own_buf, last_ptid, &last_status);
+      prepare_resume_reply (own_buf, cs.last_ptid, &cs.last_status);
 
       /* In non-stop, sending a resume reply doesn't set the general
         thread, but GDB assumes a vRun sets it (this is so GDB can
         query which is the main thread of the new inferior.  */
       if (non_stop)
-       general_thread = last_ptid;
+       cs.general_thread = cs.last_ptid;
 
       return 1;
     }
@@ -3065,18 +3073,22 @@ handle_v_run (char *own_buf)
 static int
 handle_v_kill (char *own_buf)
 {
+  client_state &cs = get_client_state ();
   int pid;
   char *p = &own_buf[6];
-  if (multi_process)
+  if (cs.multi_process)
     pid = strtol (p, NULL, 16);
   else
     pid = signal_pid;
-  if (pid != 0 && kill_inferior (pid) == 0)
+
+  process_info *proc = find_process_pid (pid);
+
+  if (proc != nullptr && kill_inferior (proc) == 0)
     {
-      last_status.kind = TARGET_WAITKIND_SIGNALLED;
-      last_status.value.sig = GDB_SIGNAL_KILL;
-      last_ptid = pid_to_ptid (pid);
-      discard_queued_stop_replies (last_ptid);
+      cs.last_status.kind = TARGET_WAITKIND_SIGNALLED;
+      cs.last_status.value.sig = GDB_SIGNAL_KILL;
+      cs.last_ptid = ptid_t (pid);
+      discard_queued_stop_replies (cs.last_ptid);
       write_ok (own_buf);
       return 1;
     }
@@ -3091,6 +3103,7 @@ handle_v_kill (char *own_buf)
 void
 handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 {
+  client_state &cs = get_client_state ();
   if (!disable_packet_vCont)
     {
       if (strcmp (own_buf, "vCtrlC") == 0)
@@ -3112,7 +3125,7 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 
          if (target_supports_hardware_single_step ()
              || target_supports_software_single_step ()
-             || !vCont_supported)
+             || !cs.vCont_supported)
            {
              /* If target supports single step either by hardware or by
                 software, add actions s and S to the list of supported
@@ -3138,7 +3151,7 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 
   if (startswith (own_buf, "vAttach;"))
     {
-      if ((!extended_protocol || !multi_process) && target_running ())
+      if ((!extended_protocol || !cs.multi_process) && target_running ())
        {
          fprintf (stderr, "Already debugging a process\n");
          write_enn (own_buf);
@@ -3150,7 +3163,7 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 
   if (startswith (own_buf, "vRun;"))
     {
-      if ((!extended_protocol || !multi_process) && target_running ())
+      if ((!extended_protocol || !cs.multi_process) && target_running ())
        {
          fprintf (stderr, "Already debugging a process\n");
          write_enn (own_buf);
@@ -3187,12 +3200,13 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 static void
 myresume (char *own_buf, int step, int sig)
 {
+  client_state &cs = get_client_state ();
   struct thread_resume resume_info[2];
   int n = 0;
   int valid_cont_thread;
 
-  valid_cont_thread = (!ptid_equal (cont_thread, null_ptid)
-                        && !ptid_equal (cont_thread, minus_one_ptid));
+  valid_cont_thread = (cs.cont_thread != null_ptid
+                        && cs.cont_thread != minus_one_ptid);
 
   if (step || sig || valid_cont_thread)
     {
@@ -3216,7 +3230,7 @@ myresume (char *own_buf, int step, int sig)
   resume (resume_info, n);
 }
 
-/* Callback for for_each_inferior.  Make a new stop reply for each
+/* Callback for for_each_thread.  Make a new stop reply for each
    stopped thread.  */
 
 static void
@@ -3281,19 +3295,10 @@ gdb_wants_thread_stopped (thread_info *thread)
 static void
 gdb_wants_all_threads_stopped (void)
 {
-  for_each_inferior (&all_threads, gdb_wants_thread_stopped);
+  for_each_thread (gdb_wants_thread_stopped);
 }
 
-/* Callback for for_each_inferior.  Clear the thread's pending status
-   flag.  */
-
-static void
-clear_pending_status_callback (thread_info *thread)
-{
-  thread->status_pending_p = 0;
-}
-
-/* Callback for for_each_inferior.  If the thread is stopped with an
+/* Callback for for_each_thread.  If the thread is stopped with an
    interesting event, mark it as having a pending event.  */
 
 static void
@@ -3316,6 +3321,8 @@ set_pending_status_callback (thread_info *thread)
 static void
 handle_status (char *own_buf)
 {
+  client_state &cs = get_client_state ();
+
   /* GDB is connected, don't forward events to the target anymore.  */
   for_each_process ([] (process_info *process) {
     process->gdb_detached = 0;
@@ -3332,7 +3339,7 @@ handle_status (char *own_buf)
       /* The first is sent immediatly.  OK is sent if there is no
         stopped thread, which is the same handling of the vStopped
         packet (by design).  */
-      notif_write_event (&notif_stop, own_buf);
+      notif_write_event (&notif_stop, cs.own_buf);
     }
   else
     {
@@ -3348,21 +3355,21 @@ handle_status (char *own_buf)
         reporting now pending.  They'll be reported the next time the
         threads are resumed.  Start by marking all interesting events
         as pending.  */
-      for_each_inferior (&all_threads, set_pending_status_callback);
+      for_each_thread (set_pending_status_callback);
 
       /* Prefer the last thread that reported an event to GDB (even if
         that was a GDB_SIGNAL_TRAP).  */
-      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);
+      if (cs.last_status.kind != TARGET_WAITKIND_IGNORE
+         && cs.last_status.kind != TARGET_WAITKIND_EXITED
+         && cs.last_status.kind != TARGET_WAITKIND_SIGNALLED)
+       thread = find_thread_ptid (cs.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_thread ([] (thread_info *thread)
+       thread = find_thread ([] (thread_info *thr_arg)
          {
-           return thread->status_pending_p;
+           return thr_arg->status_pending_p;
          });
 
       /* If we're still out of luck, simply pick the first thread in
@@ -3380,7 +3387,7 @@ handle_status (char *own_buf)
 
          /* GDB assumes the current thread is the thread we're
             reporting the status for.  */
-         general_thread = thread->id;
+         cs.general_thread = thread->id;
          set_desired_thread ();
 
          gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
@@ -3395,7 +3402,7 @@ static void
 gdbserver_version (void)
 {
   printf ("GNU gdbserver %s%s\n"
-         "Copyright (C) 2017 Free Software Foundation, Inc.\n"
+         "Copyright (C) 2018 Free Software Foundation, Inc.\n"
          "gdbserver is free software, covered by the "
          "GNU General Public License.\n"
          "This gdbserver was configured as \"%s\"\n",
@@ -3477,10 +3484,8 @@ gdbserver_show_disableable (FILE *stream)
 static void
 kill_inferior_callback (process_info *process)
 {
-  int pid = process->pid;
-
-  kill_inferior (pid);
-  discard_queued_stop_replies (pid_to_ptid (pid));
+  kill_inferior (process);
+  discard_queued_stop_replies (ptid_t (process->pid));
 }
 
 /* Call this when exiting gdbserver with possible inferiors that need
@@ -3522,11 +3527,11 @@ detach_or_kill_for_exit (void)
     int pid = process->pid;
 
     if (process->attached)
-      detach_inferior (pid);
+      detach_inferior (process);
     else
-      kill_inferior (pid);
+      kill_inferior (process);
 
-    discard_queued_stop_replies (pid_to_ptid (pid));
+    discard_queued_stop_replies (ptid_t (pid));
   });
 }
 
@@ -3568,7 +3573,18 @@ captured_main (int argc, char *argv[])
   volatile int attach = 0;
   int was_running;
   bool selftest = false;
+#if GDB_SELF_TEST
   const char *selftest_filter = NULL;
+#endif
+
+  current_directory = getcwd (NULL, 0);
+  client_state &cs = get_client_state ();
+
+  if (current_directory == NULL)
+    {
+      error (_("Could not find current working directory: %s"),
+            safe_strerror (errno));
+    }
 
   while (*next_arg != NULL && **next_arg == '-')
     {
@@ -3619,13 +3635,13 @@ captured_main (int argc, char *argv[])
        debug_threads = 1;
       else if (startswith (*next_arg, "--debug-format="))
        {
-         char *error_msg
+         std::string error_msg
            = parse_debug_format_options ((*next_arg)
                                          + sizeof ("--debug-format=") - 1, 0);
 
-         if (error_msg != NULL)
+         if (!error_msg.empty ())
            {
-             fprintf (stderr, "%s", error_msg);
+             fprintf (stderr, "%s", error_msg.c_str ());
              exit (1);
            }
        }
@@ -3678,9 +3694,9 @@ captured_main (int argc, char *argv[])
          break;
        }
       else if (strcmp (*next_arg, "--disable-randomization") == 0)
-       disable_randomization = 1;
+       cs.disable_randomization = 1;
       else if (strcmp (*next_arg, "--no-disable-randomization") == 0)
-       disable_randomization = 0;
+       cs.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)
@@ -3692,7 +3708,9 @@ captured_main (int argc, char *argv[])
       else if (startswith (*next_arg, "--selftest="))
        {
          selftest = true;
+#if GDB_SELF_TEST
          selftest_filter = *next_arg + strlen ("--selftest=");
+#endif
        }
       else
        {
@@ -3720,7 +3738,7 @@ captured_main (int argc, char *argv[])
      opened by remote_prepare.  */
   notice_open_fds ();
 
-  save_original_signals_state ();
+  save_original_signals_state (false);
 
   /* We need to know whether the remote connection is stdio before
      starting the inferior.  Inferiors created in this scenario have
@@ -3765,12 +3783,15 @@ captured_main (int argc, char *argv[])
     initialize_tracepoint ();
   initialize_notif ();
 
-  own_buf = (char *) xmalloc (PBUFSIZ + 1);
   mem_buf = (unsigned char *) xmalloc (PBUFSIZ);
 
   if (selftest)
     {
+#if GDB_SELF_TEST
       selftests::run_tests (selftest_filter);
+#else
+      printf (_("Selftests have been disabled for this build.\n"));
+#endif
       throw_quit ("Quit");
     }
 
@@ -3779,13 +3800,13 @@ captured_main (int argc, char *argv[])
       int i, n;
 
       n = argc - (next_arg - argv);
-      program_name = xstrdup (next_arg[0]);
+      program_path.set (gdb::unique_xmalloc_ptr<char> (xstrdup (next_arg[0])));
       for (i = 1; i < n; i++)
        program_args.push_back (xstrdup (next_arg[i]));
       program_args.push_back (NULL);
 
       /* Wait till we are at first instruction in program.  */
-      create_inferior (program_name, program_args);
+      create_inferior (program_path.get (), program_args);
 
       /* We are now (hopefully) stopped at the first instruction of
         the target process.  This assumes that the target process was
@@ -3800,9 +3821,9 @@ captured_main (int argc, char *argv[])
     }
   else
     {
-      last_status.kind = TARGET_WAITKIND_EXITED;
-      last_status.value.integer = 0;
-      last_ptid = minus_one_ptid;
+      cs.last_status.kind = TARGET_WAITKIND_EXITED;
+      cs.last_status.value.integer = 0;
+      cs.last_ptid = minus_one_ptid;
     }
   make_cleanup (detach_or_kill_for_exit_cleanup, NULL);
 
@@ -3811,8 +3832,8 @@ captured_main (int argc, char *argv[])
      shared library event" notice on gdb side.  */
   dlls_changed = 0;
 
-  if (last_status.kind == TARGET_WAITKIND_EXITED
-      || last_status.kind == TARGET_WAITKIND_SIGNALLED)
+  if (cs.last_status.kind == TARGET_WAITKIND_EXITED
+      || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)
     was_running = 0;
   else
     was_running = 1;
@@ -3822,18 +3843,17 @@ captured_main (int argc, char *argv[])
 
   while (1)
     {
-
-      noack_mode = 0;
-      multi_process = 0;
-      report_fork_events = 0;
-      report_vfork_events = 0;
-      report_exec_events = 0;
+      cs.noack_mode = 0;
+      cs.multi_process = 0;
+      cs.report_fork_events = 0;
+      cs.report_vfork_events = 0;
+      cs.report_exec_events = 0;
       /* Be sure we're out of tfind mode.  */
-      current_traceframe = -1;
-      cont_thread = null_ptid;
-      swbreak_feature = 0;
-      hwbreak_feature = 0;
-      vCont_supported = 0;
+      cs.current_traceframe = -1;
+      cs.cont_thread = null_ptid;
+      cs.swbreak_feature = 0;
+      cs.hwbreak_feature = 0;
+      cs.vCont_supported = 0;
 
       remote_open (port);
 
@@ -3869,8 +3889,10 @@ captured_main (int argc, char *argv[])
             (by the same GDB instance or another) will refresh all its
             state from scratch.  */
          discard_queued_stop_replies (minus_one_ptid);
-         for_each_inferior (&all_threads,
-                            clear_pending_status_callback);
+         for_each_thread ([] (thread_info *thread)
+           {
+             thread->status_pending_p = 0;
+           });
 
          if (tracing)
            {
@@ -3907,8 +3929,8 @@ captured_main (int argc, char *argv[])
 
          if (response_needed)
            {
-             write_enn (own_buf);
-             putpkt (own_buf);
+             write_enn (cs.own_buf);
+             putpkt (cs.own_buf);
            }
 
          if (run_once)
@@ -4003,9 +4025,9 @@ process_point_options (struct gdb_breakpoint *bp, const char **packet)
 static int
 process_serial_event (void)
 {
+  client_state &cs = get_client_state ();
   int signal;
   unsigned int len;
-  int res;
   CORE_ADDR mem_addr;
   unsigned char sig;
   int packet_len;
@@ -4014,7 +4036,7 @@ process_serial_event (void)
   disable_async_io ();
 
   response_needed = 0;
-  packet_len = getpkt (own_buf);
+  packet_len = getpkt (cs.own_buf);
   if (packet_len <= 0)
     {
       remote_close ();
@@ -4023,31 +4045,31 @@ process_serial_event (void)
     }
   response_needed = 1;
 
-  char ch = own_buf[0];
+  char ch = cs.own_buf[0];
   switch (ch)
     {
     case 'q':
-      handle_query (own_buf, packet_len, &new_packet_len);
+      handle_query (cs.own_buf, packet_len, &new_packet_len);
       break;
     case 'Q':
-      handle_general_set (own_buf);
+      handle_general_set (cs.own_buf);
       break;
     case 'D':
-      handle_detach (own_buf);
+      handle_detach (cs.own_buf);
       break;
     case '!':
       extended_protocol = 1;
-      write_ok (own_buf);
+      write_ok (cs.own_buf);
       break;
     case '?':
-      handle_status (own_buf);
+      handle_status (cs.own_buf);
       break;
     case 'H':
-      if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
+      if (cs.own_buf[1] == 'c' || cs.own_buf[1] == 'g' || cs.own_buf[1] == 's')
        {
-         require_running_or_break (own_buf);
+         require_running_or_break (cs.own_buf);
 
-         ptid_t thread_id = read_ptid (&own_buf[2], NULL);
+         ptid_t thread_id = read_ptid (&cs.own_buf[2], NULL);
 
          if (thread_id == null_ptid || thread_id == minus_one_ptid)
            thread_id = null_ptid;
@@ -4058,7 +4080,7 @@ process_serial_event (void)
 
              if (thread == NULL)
                {
-                 write_enn (own_buf);
+                 write_enn (cs.own_buf);
                  break;
                }
 
@@ -4069,54 +4091,52 @@ process_serial_event (void)
              /* The ptid represents a lwp/tid.  */
              if (find_thread_ptid (thread_id) == NULL)
                {
-                 write_enn (own_buf);
+                 write_enn (cs.own_buf);
                  break;
                }
            }
 
-         if (own_buf[1] == 'g')
+         if (cs.own_buf[1] == 'g')
            {
-             if (ptid_equal (thread_id, null_ptid))
+             if (thread_id == null_ptid)
                {
                  /* 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 (cs.general_thread);
                  if (thread == NULL)
                    thread = get_first_thread ();
                  thread_id = thread->id;
                }
 
-             general_thread = thread_id;
+             cs.general_thread = thread_id;
              set_desired_thread ();
              gdb_assert (current_thread != NULL);
            }
-         else if (own_buf[1] == 'c')
-           cont_thread = thread_id;
+         else if (cs.own_buf[1] == 'c')
+           cs.cont_thread = thread_id;
 
-         write_ok (own_buf);
+         write_ok (cs.own_buf);
        }
       else
        {
          /* Silently ignore it so that gdb can extend the protocol
             without compatibility headaches.  */
-         own_buf[0] = '\0';
+         cs.own_buf[0] = '\0';
        }
       break;
     case 'g':
-      require_running_or_break (own_buf);
-      if (current_traceframe >= 0)
+      require_running_or_break (cs.own_buf);
+      if (cs.current_traceframe >= 0)
        {
          struct regcache *regcache
            = new_register_cache (current_target_desc ());
 
-         if (fetch_traceframe_registers (current_traceframe,
+         if (fetch_traceframe_registers (cs.current_traceframe,
                                          regcache, -1) == 0)
-           registers_to_string (regcache, own_buf);
+           registers_to_string (regcache, cs.own_buf);
          else
-           write_enn (own_buf);
+           write_enn (cs.own_buf);
          free_register_cache (regcache);
        }
       else
@@ -4124,85 +4144,87 @@ process_serial_event (void)
          struct regcache *regcache;
 
          if (!set_desired_thread ())
-           write_enn (own_buf);
+           write_enn (cs.own_buf);
          else
            {
              regcache = get_thread_regcache (current_thread, 1);
-             registers_to_string (regcache, own_buf);
+             registers_to_string (regcache, cs.own_buf);
            }
        }
       break;
     case 'G':
-      require_running_or_break (own_buf);
-      if (current_traceframe >= 0)
-       write_enn (own_buf);
+      require_running_or_break (cs.own_buf);
+      if (cs.current_traceframe >= 0)
+       write_enn (cs.own_buf);
       else
        {
          struct regcache *regcache;
 
          if (!set_desired_thread ())
-           write_enn (own_buf);
+           write_enn (cs.own_buf);
          else
            {
              regcache = get_thread_regcache (current_thread, 1);
-             registers_from_string (regcache, &own_buf[1]);
-             write_ok (own_buf);
+             registers_from_string (regcache, &cs.own_buf[1]);
+             write_ok (cs.own_buf);
            }
        }
       break;
     case 'm':
-      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)
-       write_enn (own_buf);
-      else
-       bin2hex (mem_buf, own_buf, res);
+      {
+       require_running_or_break (cs.own_buf);
+       decode_m_packet (&cs.own_buf[1], &mem_addr, &len);
+       int res = gdb_read_memory (mem_addr, mem_buf, len);
+       if (res < 0)
+         write_enn (cs.own_buf);
+       else
+         bin2hex (mem_buf, cs.own_buf, res);
+      }
       break;
     case 'M':
-      require_running_or_break (own_buf);
-      decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
+      require_running_or_break (cs.own_buf);
+      decode_M_packet (&cs.own_buf[1], &mem_addr, &len, &mem_buf);
       if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
-       write_ok (own_buf);
+       write_ok (cs.own_buf);
       else
-       write_enn (own_buf);
+       write_enn (cs.own_buf);
       break;
     case 'X':
-      require_running_or_break (own_buf);
-      if (decode_X_packet (&own_buf[1], packet_len - 1,
+      require_running_or_break (cs.own_buf);
+      if (decode_X_packet (&cs.own_buf[1], packet_len - 1,
                           &mem_addr, &len, &mem_buf) < 0
          || gdb_write_memory (mem_addr, mem_buf, len) != 0)
-       write_enn (own_buf);
+       write_enn (cs.own_buf);
       else
-       write_ok (own_buf);
+       write_ok (cs.own_buf);
       break;
     case 'C':
-      require_running_or_break (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running_or_break (cs.own_buf);
+      hex2bin (cs.own_buf + 1, &sig, 1);
       if (gdb_signal_to_host_p ((enum gdb_signal) sig))
        signal = gdb_signal_to_host ((enum gdb_signal) sig);
       else
        signal = 0;
-      myresume (own_buf, 0, signal);
+      myresume (cs.own_buf, 0, signal);
       break;
     case 'S':
-      require_running_or_break (own_buf);
-      hex2bin (own_buf + 1, &sig, 1);
+      require_running_or_break (cs.own_buf);
+      hex2bin (cs.own_buf + 1, &sig, 1);
       if (gdb_signal_to_host_p ((enum gdb_signal) sig))
        signal = gdb_signal_to_host ((enum gdb_signal) sig);
       else
        signal = 0;
-      myresume (own_buf, 1, signal);
+      myresume (cs.own_buf, 1, signal);
       break;
     case 'c':
-      require_running_or_break (own_buf);
+      require_running_or_break (cs.own_buf);
       signal = 0;
-      myresume (own_buf, 0, signal);
+      myresume (cs.own_buf, 0, signal);
       break;
     case 's':
-      require_running_or_break (own_buf);
+      require_running_or_break (cs.own_buf);
       signal = 0;
-      myresume (own_buf, 1, signal);
+      myresume (cs.own_buf, 1, signal);
       break;
     case 'Z':  /* insert_ ... */
       /* Fallthrough.  */
@@ -4211,10 +4233,10 @@ process_serial_event (void)
        char *dataptr;
        ULONGEST addr;
        int kind;
-       char type = own_buf[1];
+       char type = cs.own_buf[1];
        int res;
        const int insert = ch == 'Z';
-       const char *p = &own_buf[3];
+       const char *p = &cs.own_buf[3];
 
        p = unpack_varlen_hex (p, &addr);
        kind = strtol (p + 1, &dataptr, 16);
@@ -4242,12 +4264,12 @@ process_serial_event (void)
          res = delete_gdb_breakpoint (type, addr, kind);
 
        if (res == 0)
-         write_ok (own_buf);
+         write_ok (cs.own_buf);
        else if (res == 1)
          /* Unsupported.  */
-         own_buf[0] = '\0';
+         cs.own_buf[0] = '\0';
        else
-         write_enn (own_buf);
+         write_enn (cs.own_buf);
        break;
       }
     case 'k':
@@ -4265,8 +4287,8 @@ process_serial_event (void)
         running.  The traditional protocol will exit instead.  */
       if (extended_protocol)
        {
-         last_status.kind = TARGET_WAITKIND_EXITED;
-         last_status.value.sig = GDB_SIGNAL_KILL;
+         cs.last_status.kind = TARGET_WAITKIND_EXITED;
+         cs.last_status.value.sig = GDB_SIGNAL_KILL;
          return 0;
        }
       else
@@ -4274,19 +4296,19 @@ process_serial_event (void)
 
     case 'T':
       {
-       require_running_or_break (own_buf);
+       require_running_or_break (cs.own_buf);
 
-       ptid_t thread_id = read_ptid (&own_buf[1], NULL);
+       ptid_t thread_id = read_ptid (&cs.own_buf[1], NULL);
        if (find_thread_ptid (thread_id) == NULL)
          {
-           write_enn (own_buf);
+           write_enn (cs.own_buf);
            break;
          }
 
        if (mythread_alive (thread_id))
-         write_ok (own_buf);
+         write_ok (cs.own_buf);
        else
-         write_enn (own_buf);
+         write_enn (cs.own_buf);
       }
       break;
     case 'R':
@@ -4302,26 +4324,26 @@ process_serial_event (void)
          fprintf (stderr, "GDBserver restarting\n");
 
          /* Wait till we are at 1st instruction in prog.  */
-         if (program_name != NULL)
+         if (program_path.get () != NULL)
            {
-             create_inferior (program_name, program_args);
+             create_inferior (program_path.get (), program_args);
 
-             if (last_status.kind == TARGET_WAITKIND_STOPPED)
+             if (cs.last_status.kind == TARGET_WAITKIND_STOPPED)
                {
                  /* Stopped at the first instruction of the target
                     process.  */
-                 general_thread = last_ptid;
+                 cs.general_thread = cs.last_ptid;
                }
              else
                {
                  /* Something went wrong.  */
-                 general_thread = null_ptid;
+                 cs.general_thread = null_ptid;
                }
            }
          else
            {
-             last_status.kind = TARGET_WAITKIND_EXITED;
-             last_status.value.sig = GDB_SIGNAL_KILL;
+             cs.last_status.kind = TARGET_WAITKIND_EXITED;
+             cs.last_status.value.sig = GDB_SIGNAL_KILL;
            }
          return 0;
        }
@@ -4330,26 +4352,26 @@ process_serial_event (void)
          /* It is a request we don't understand.  Respond with an
             empty packet so that gdb knows that we don't support this
             request.  */
-         own_buf[0] = '\0';
+         cs.own_buf[0] = '\0';
          break;
        }
     case 'v':
       /* Extended (long) request.  */
-      handle_v_requests (own_buf, packet_len, &new_packet_len);
+      handle_v_requests (cs.own_buf, packet_len, &new_packet_len);
       break;
 
     default:
       /* It is a request we don't understand.  Respond with an empty
         packet so that gdb knows that we don't support this
         request.  */
-      own_buf[0] = '\0';
+      cs.own_buf[0] = '\0';
       break;
     }
 
   if (new_packet_len != -1)
-    putpkt_binary (own_buf, new_packet_len);
+    putpkt_binary (cs.own_buf, new_packet_len);
   else
-    putpkt (own_buf);
+    putpkt (cs.own_buf);
 
   response_needed = 0;
 
@@ -4396,30 +4418,31 @@ push_stop_notification (ptid_t ptid, struct target_waitstatus *status)
 int
 handle_target_event (int err, gdb_client_data client_data)
 {
+  client_state &cs = get_client_state ();
   if (debug_threads)
     debug_printf ("handling possible target event\n");
 
-  last_ptid = mywait (minus_one_ptid, &last_status,
+  cs.last_ptid = mywait (minus_one_ptid, &cs.last_status,
                      TARGET_WNOHANG, 1);
 
-  if (last_status.kind == TARGET_WAITKIND_NO_RESUMED)
+  if (cs.last_status.kind == TARGET_WAITKIND_NO_RESUMED)
     {
       if (gdb_connected () && report_no_resumed)
-       push_stop_notification (null_ptid, &last_status);
+       push_stop_notification (null_ptid, &cs.last_status);
     }
-  else if (last_status.kind != TARGET_WAITKIND_IGNORE)
+  else if (cs.last_status.kind != TARGET_WAITKIND_IGNORE)
     {
-      int pid = ptid_get_pid (last_ptid);
+      int pid = cs.last_ptid.pid ();
       struct process_info *process = find_process_pid (pid);
       int forward_event = !gdb_connected () || process->gdb_detached;
 
-      if (last_status.kind == TARGET_WAITKIND_EXITED
-         || last_status.kind == TARGET_WAITKIND_SIGNALLED)
+      if (cs.last_status.kind == TARGET_WAITKIND_EXITED
+         || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED)
        {
          mark_breakpoints_out (process);
-         target_mourn_inferior (last_ptid);
+         target_mourn_inferior (cs.last_ptid);
        }
-      else if (last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
+      else if (cs.last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
        ;
       else
        {
@@ -4427,7 +4450,7 @@ handle_target_event (int err, gdb_client_data client_data)
             "want-stopped" state to what the client wants, until it
             gets a new resume action.  */
          current_thread->last_resume_kind = resume_stop;
-         current_thread->last_status = last_status;
+         current_thread->last_status = cs.last_status;
        }
 
       if (forward_event)
@@ -4438,9 +4461,9 @@ handle_target_event (int err, gdb_client_data client_data)
              exit (0);
            }
 
-         if (last_status.kind == TARGET_WAITKIND_EXITED
-             || last_status.kind == TARGET_WAITKIND_SIGNALLED
-             || last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
+         if (cs.last_status.kind == TARGET_WAITKIND_EXITED
+             || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED
+             || cs.last_status.kind == TARGET_WAITKIND_THREAD_EXITED)
            ;
          else
            {
@@ -4452,18 +4475,18 @@ handle_target_event (int err, gdb_client_data client_data)
              if (debug_threads)
                debug_printf ("GDB not connected; forwarding event %d for"
                              " [%s]\n",
-                             (int) last_status.kind,
-                             target_pid_to_str (last_ptid));
+                             (int) cs.last_status.kind,
+                             target_pid_to_str (cs.last_ptid));
 
-             if (last_status.kind == TARGET_WAITKIND_STOPPED)
-               signal = last_status.value.sig;
+             if (cs.last_status.kind == TARGET_WAITKIND_STOPPED)
+               signal = cs.last_status.value.sig;
              else
                signal = GDB_SIGNAL_0;
-             target_continue (last_ptid, signal);
+             target_continue (cs.last_ptid, signal);
            }
        }
       else
-       push_stop_notification (last_ptid, &last_status);
+       push_stop_notification (cs.last_ptid, &cs.last_status);
     }
 
   /* Be sure to not change the selected thread behind GDB's back.
This page took 0.053355 seconds and 4 git commands to generate.