Add thread_handle_to_thread_info support for remote targets
[deliverable/binutils-gdb.git] / gdb / gdbserver / server.c
index 38383510e8bff76792c0a246482b9dba9665ac2b..f3eee31052b6f55434f96975e791fc55c3caafa1 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.  */
 
 static gdb_environ our_environ;
@@ -631,6 +647,67 @@ handle_general_set (char *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)
@@ -810,12 +887,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
@@ -890,7 +969,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;
@@ -917,7 +996,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;
@@ -1078,12 +1157,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".
@@ -1342,21 +1508,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.  */
 
@@ -1364,24 +1515,12 @@ 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;
+  std::string *document = (std::string *) arg;
+  std::string name = xml_escape_text (dll->name);
+
+  *document += string_printf
+    ("  <library name=\"%s\"><segment address=\"0x%lx\"/></library>\n",
+     name.c_str (), (long) dll->base_addr);
 }
 
 /* Handle qXfer:libraries:read.  */
@@ -1391,43 +1530,26 @@ 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);
+  std::string document = "<library-list version=\"1.0\">\n";
 
-  document = (char *) malloc (total_len);
-  if (document == NULL)
-    return -1;
+  for_each_inferior_with_data (&all_dlls, emit_dll_description, &document);
 
-  strcpy (document, "<library-list version=\"1.0\">\n");
-  p = document + strlen (document);
+  document += "</library-list>\n";
 
-  for_each_inferior_with_data (&all_dlls, emit_dll_description, &p);
-
-  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;
 }
 
@@ -1521,11 +1643,14 @@ handle_qxfer_threads_worker (struct inferior_list_entry *inf, 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);
 
@@ -1540,6 +1665,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");
 }
 
@@ -2005,21 +2137,20 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
   /* 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);
+         ptid = thread_ptr->id;
        }
 
       sprintf (own_buf, "QC");
       own_buf += 2;
-      write_ptid (own_buf, gdb_id);
+      write_ptid (own_buf, ptid);
       return;
     }
 
@@ -2075,28 +2206,22 @@ 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);
+         require_running_or_return (own_buf);
          thread_ptr = get_first_inferior (&all_threads);
 
          *own_buf++ = 'm';
-         gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
-         write_ptid (own_buf, gdb_id);
+         write_ptid (own_buf, thread_ptr->id);
          thread_ptr = thread_ptr->next;
          return;
        }
 
       if (strcmp ("qsThreadInfo", own_buf) == 0)
        {
-         ptid_t gdb_id;
-
-         require_running (own_buf);
+         require_running_or_return (own_buf);
          if (thread_ptr != NULL)
            {
              *own_buf++ = 'm';
-             gdb_id = thread_to_gdb_id ((struct thread_info *)thread_ptr);
-             write_ptid (own_buf, gdb_id);
+             write_ptid (own_buf, thread_ptr->id);
              thread_ptr = thread_ptr->next;
              return;
            }
@@ -2113,7 +2238,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);
@@ -2228,7 +2353,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
        }
 
       sprintf (own_buf,
-              "PacketSize=%x;QPassSignals+;QProgramSignals+;QStartupWithShell+",
+              "PacketSize=%x;QPassSignals+;QProgramSignals+;"
+              "QStartupWithShell+;QEnvironmentHexEncoded+;"
+              "QEnvironmentReset+;QEnvironmentUnset+",
               PBUFSIZ - 1);
 
       if (target_supports_catch_syscall ())
@@ -2348,7 +2475,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++)
        {
@@ -2461,7 +2588,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;
     }
@@ -2479,7 +2606,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
        }
       else
        {
-         require_running (own_buf);
+         require_running_or_return (own_buf);
          process = current_process ();
        }
 
@@ -2501,7 +2628,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       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++ != ',')
        {
@@ -3116,14 +3243,12 @@ 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);
+                           status_string.c_str ());
            }
 
          gdb_assert (thread->last_status.kind != TARGET_WAITKIND_IGNORE);
@@ -3283,7 +3408,7 @@ 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);
@@ -3376,26 +3501,6 @@ 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)
 {
@@ -3521,6 +3626,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 == '-')
     {
@@ -3639,6 +3746,13 @@ captured_main (int argc, char *argv[])
        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);
@@ -3654,7 +3768,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);
@@ -3670,7 +3785,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;
@@ -3711,6 +3827,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;
@@ -3940,13 +4062,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;
@@ -3963,8 +4082,7 @@ process_serial_event (void)
     }
   response_needed = 1;
 
-  i = 0;
-  ch = own_buf[i++];
+  char ch = own_buf[0];
   switch (ch)
     {
     case 'q':
@@ -3974,91 +4092,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;
@@ -4070,27 +4104,18 @@ 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;
@@ -4100,8 +4125,8 @@ process_serial_event (void)
            }
          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;
@@ -4124,7 +4149,7 @@ process_serial_event (void)
                }
 
              general_thread = thread_id;
-             set_desired_thread (1);
+             set_desired_thread ();
              gdb_assert (current_thread != NULL);
            }
          else if (own_buf[1] == 'c')
@@ -4140,7 +4165,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
@@ -4157,7 +4182,7 @@ process_serial_event (void)
        {
          struct regcache *regcache;
 
-         if (!set_desired_thread (1))
+         if (!set_desired_thread ())
            write_enn (own_buf);
          else
            {
@@ -4167,14 +4192,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
            {
@@ -4185,7 +4210,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)
@@ -4194,7 +4219,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);
@@ -4202,7 +4227,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)
@@ -4211,7 +4236,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);
@@ -4220,7 +4245,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);
@@ -4229,12 +4254,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;
@@ -4306,13 +4331,10 @@ process_serial_event (void)
 
     case 'T':
       {
-       ptid_t gdb_id, thread_id;
+       require_running_or_break (own_buf);
 
-       require_running (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;
@@ -4408,7 +4430,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;
 }
@@ -4503,7 +4525,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.035688 seconds and 4 git commands to generate.