2011-05-18 Pedro Alves <pedro@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / thread.c
index d4cd8556c54a99c99c430402cd631c6241f7f15b..5f07c83ff3b84aa9daa9d13d5804d0f387cde96e 100644 (file)
@@ -44,6 +44,7 @@
 #include "annotate.h"
 #include "cli/cli-decode.h"
 #include "gdb_regex.h"
+#include "cli/cli-utils.h"
 
 /* Definition of struct thread_info exported to gdbthread.h.  */
 
@@ -469,18 +470,18 @@ struct thread_info *
 any_live_thread_of_process (int pid)
 {
   struct thread_info *tp;
-  struct thread_info *tp_running = NULL;
+  struct thread_info *tp_executing = NULL;
 
   for (tp = thread_list; tp; tp = tp->next)
-    if (ptid_get_pid (tp->ptid) == pid)
+    if (tp->state_ != THREAD_EXITED && ptid_get_pid (tp->ptid) == pid)
       {
-       if (tp->state_ == THREAD_STOPPED)
+       if (tp->executing_)
+         tp_executing = tp;
+       else
          return tp;
-       else if (tp->state_ == THREAD_RUNNING)
-         tp_running = tp;
       }
 
-  return tp_running;
+  return tp_executing;
 }
 
 /* Print a list of thread ids currently known, and the total number of
@@ -755,7 +756,7 @@ finish_thread_state_cleanup (void *arg)
 }
 
 /* Prints the list of threads and their details on UIOUT.
-   This is a version of 'info_thread_command' suitable for
+   This is a version of 'info_threads_command' suitable for
    use from MI.
    If REQUESTED_THREAD is not -1, it's the GDB id of the thread
    that should be printed.  Otherwise, all threads are
@@ -766,7 +767,7 @@ finish_thread_state_cleanup (void *arg)
    is printed if it belongs to the specified process.  Otherwise,
    an error is raised.  */
 void
-print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
+print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
 {
   struct thread_info *tp;
   ptid_t current_ptid;
@@ -791,7 +792,7 @@ print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
 
       for (tp = thread_list; tp; tp = tp->next)
        {
-         if (requested_thread != -1 && tp->num != requested_thread)
+         if (!number_is_in_list (requested_threads, tp->num))
            continue;
 
          if (pid != -1 && PIDGET (tp->ptid) != pid)
@@ -805,10 +806,11 @@ print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
 
       if (n_threads == 0)
        {
-         if (requested_thread == -1)
+         if (requested_threads == NULL || *requested_threads == '\0')
            ui_out_message (uiout, 0, _("No threads.\n"));
          else
-           ui_out_message (uiout, 0, _("No thread %d.\n"), requested_thread);
+           ui_out_message (uiout, 0, _("No threads match '%s'.\n"),
+                           requested_threads);
          do_cleanups (old_chain);
          return;
        }
@@ -827,12 +829,12 @@ print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
       struct cleanup *chain2;
       int core;
 
-      if (requested_thread != -1 && tp->num != requested_thread)
+      if (!number_is_in_list (requested_threads, tp->num))
        continue;
 
       if (pid != -1 && PIDGET (tp->ptid) != pid)
        {
-         if (requested_thread != -1)
+         if (requested_threads != NULL && *requested_threads != '\0')
            error (_("Requested thread not found in requested process"));
          continue;
        }
@@ -935,7 +937,7 @@ print_thread_info (struct ui_out *uiout, int requested_thread, int pid)
      the "info threads" command.  */
   do_cleanups (old_chain);
 
-  if (pid == -1 && requested_thread == -1)
+  if (pid == -1 && requested_threads == NULL)
     {
       gdb_assert (current_thread != -1
                  || !thread_list
@@ -966,43 +968,7 @@ No selected thread.  See `help thread'.\n");
 static void
 info_threads_command (char *arg, int from_tty)
 {
-  int tid = -1;
-
-  if (arg == NULL || *arg == '\0')
-    {
-      print_thread_info (uiout, -1, -1);
-      return;
-    }
-
-  while (arg != NULL && *arg != '\0')
-    {
-      int tmp_tid = strtol (arg, &arg, 0);
-      unsigned int highrange;
-
-      if (tmp_tid <= 0)
-       error (_("invalid thread id %d"), tmp_tid);
-
-      tid = tmp_tid;
-      print_thread_info (uiout, tid, -1);
-
-      while (*arg == ' ' || *arg == '\t')
-       ++arg;
-
-      if (*arg == '-')
-       {
-         /* Do a range of threads.  Must be in ascending order.  */
-         ++arg;        /* Skip the hyphen.  */
-         highrange = strtoul (arg, &arg, 0);
-         if (highrange < tid)
-           error (_("inverted range"));
-
-         /* Do the threads in the range (first one already done).  */
-         while (tid < highrange)
-           {
-             print_thread_info (uiout, ++tid, -1);
-           }
-       }
-    }
+  print_thread_info (uiout, arg, -1);
 }
 
 /* Switch from one thread to another.  */
@@ -1053,6 +1019,13 @@ restore_selected_frame (struct frame_id a_frame_id, int frame_level)
   struct frame_info *frame = NULL;
   int count;
 
+  /* This means there was no selected frame.  */
+  if (frame_level == -1)
+    {
+      select_frame (NULL);
+      return;
+    }
+
   gdb_assert (frame_level >= 0);
 
   /* Restore by level first, check if the frame id is the same as
@@ -1171,7 +1144,14 @@ make_cleanup_restore_current_thread (void)
          && target_has_registers
          && target_has_stack
          && target_has_memory)
-       frame = get_selected_frame (NULL);
+       {
+         /* When processing internal events, there might not be a
+            selected frame.  If we naively call get_selected_frame
+            here, then we can end up reading debuginfo for the
+            current frame, but we don't generally need the debuginfo
+            at this point.  */
+         frame = get_selected_frame_if_set ();
+       }
       else
        frame = NULL;
 
@@ -1232,9 +1212,9 @@ static void
 thread_apply_command (char *tidlist, int from_tty)
 {
   char *cmd;
-  char *p;
   struct cleanup *old_chain;
   char *saved_cmd;
+  struct get_number_or_range_state state;
 
   if (tidlist == NULL || *tidlist == '\000')
     error (_("Please specify a thread ID list"));
@@ -1248,54 +1228,34 @@ thread_apply_command (char *tidlist, int from_tty)
      execute_command.  */
   saved_cmd = xstrdup (cmd);
   old_chain = make_cleanup (xfree, saved_cmd);
-  while (tidlist < cmd)
+
+  init_number_or_range (&state, tidlist);
+  while (!state.finished && state.string < cmd)
     {
       struct thread_info *tp;
-      int start, end;
-
-      start = strtol (tidlist, &p, 10);
-      if (p == tidlist)
-       error (_("Error parsing %s"), tidlist);
-      tidlist = p;
+      int start;
+      char *p = tidlist;
 
-      while (*tidlist == ' ' || *tidlist == '\t')
-       tidlist++;
-
-      if (*tidlist == '-')     /* Got a range of IDs?  */
-       {
-         tidlist++;            /* Skip the - */
-         end = strtol (tidlist, &p, 10);
-         if (p == tidlist)
-           error (_("Error parsing %s"), tidlist);
-         tidlist = p;
-
-         while (*tidlist == ' ' || *tidlist == '\t')
-           tidlist++;
-       }
-      else
-       end = start;
+      start = get_number_or_range (&state);
 
       make_cleanup_restore_current_thread ();
 
-      for (; start <= end; start++)
-       {
-         tp = find_thread_id (start);
+      tp = find_thread_id (start);
 
-         if (!tp)
-           warning (_("Unknown thread %d."), start);
-         else if (!thread_alive (tp))
-           warning (_("Thread %d has terminated."), start);
-         else
-           {
-             switch_to_thread (tp->ptid);
+      if (!tp)
+       warning (_("Unknown thread %d."), start);
+      else if (!thread_alive (tp))
+       warning (_("Thread %d has terminated."), start);
+      else
+       {
+         switch_to_thread (tp->ptid);
 
-             printf_filtered (_("\nThread %d (%s):\n"), tp->num,
-                              target_pid_to_str (inferior_ptid));
-             execute_command (cmd, from_tty);
+         printf_filtered (_("\nThread %d (%s):\n"), tp->num,
+                          target_pid_to_str (inferior_ptid));
+         execute_command (cmd, from_tty);
 
-             /* Restore exact command used previously.  */
-             strcpy (cmd, saved_cmd);
-           }
+         /* Restore exact command used previously.  */
+         strcpy (cmd, saved_cmd);
        }
     }
 
This page took 0.027313 seconds and 4 git commands to generate.