Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / thread.c
index 52626ff..25538d7 100644 (file)
@@ -1,6 +1,6 @@
 /* Multi-process/thread control for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.
 
 #include "value.h"
 #include "target.h"
 #include "gdbthread.h"
-#include "exceptions.h"
 #include "command.h"
 #include "gdbcmd.h"
 #include "regcache.h"
 #include "gdb.h"
-#include "gdb_string.h"
 #include "btrace.h"
 
 #include <ctype.h>
@@ -57,6 +55,13 @@ void _initialize_thread (void);
 struct thread_info *thread_list = NULL;
 static int highest_thread_num;
 
+/* True if any thread is, or may be executing.  We need to track this
+   separately because until we fully sync the thread list, we won't
+   know whether the target is fully stopped, even if we see stop
+   events for all known threads, because any of those threads may have
+   spawned new threads we haven't heard of yet.  */
+static int threads_executing;
+
 static void thread_command (char *tidstr, int from_tty);
 static void thread_apply_all_command (char *, int);
 static int thread_alive (struct thread_info *);
@@ -168,6 +173,7 @@ init_thread_list (void)
     }
 
   thread_list = NULL;
+  threads_executing = 0;
 }
 
 /* Allocate a new thread with target id PTID and add it to the thread
@@ -467,7 +473,13 @@ any_thread_of_process (int pid)
 {
   struct thread_info *tp;
 
-  for (tp = thread_list; tp; tp = tp->next)
+  gdb_assert (pid != 0);
+
+  /* Prefer the current thread.  */
+  if (ptid_get_pid (inferior_ptid) == pid)
+    return inferior_thread ();
+
+  ALL_NON_EXITED_THREADS (tp)
     if (ptid_get_pid (tp->ptid) == pid)
       return tp;
 
@@ -477,18 +489,40 @@ any_thread_of_process (int pid)
 struct thread_info *
 any_live_thread_of_process (int pid)
 {
+  struct thread_info *curr_tp = NULL;
   struct thread_info *tp;
   struct thread_info *tp_executing = NULL;
 
-  for (tp = thread_list; tp; tp = tp->next)
-    if (tp->state != THREAD_EXITED && ptid_get_pid (tp->ptid) == pid)
+  gdb_assert (pid != 0);
+
+  /* Prefer the current thread if it's not executing.  */
+  if (ptid_get_pid (inferior_ptid) == pid)
+    {
+      /* If the current thread is dead, forget it.  If it's not
+        executing, use it.  Otherwise, still choose it (below), but
+        only if no other non-executing thread is found.  */
+      curr_tp = inferior_thread ();
+      if (curr_tp->state == THREAD_EXITED)
+       curr_tp = NULL;
+      else if (!curr_tp->executing)
+       return curr_tp;
+    }
+
+  ALL_NON_EXITED_THREADS (tp)
+    if (ptid_get_pid (tp->ptid) == pid)
       {
-       if (tp->executing)
-         tp_executing = tp;
-       else
+       if (!tp->executing)
          return tp;
+
+       tp_executing = tp;
       }
 
+  /* If both the current thread and all live threads are executing,
+     prefer the current thread.  */
+  if (curr_tp != NULL)
+    return curr_tp;
+
+  /* Otherwise, just return an executing thread, if any.  */
   return tp_executing;
 }
 
@@ -648,18 +682,6 @@ is_running (ptid_t ptid)
 }
 
 int
-any_running (void)
-{
-  struct thread_info *tp;
-
-  for (tp = thread_list; tp; tp = tp->next)
-    if (tp->state == THREAD_RUNNING)
-      return 1;
-
-  return 0;
-}
-
-int
 is_executing (ptid_t ptid)
 {
   struct thread_info *tp;
@@ -687,6 +709,22 @@ set_executing (ptid_t ptid, int executing)
       gdb_assert (tp);
       tp->executing = executing;
     }
+
+  /* It only takes one running thread to spawn more threads.*/
+  if (executing)
+    threads_executing = 1;
+  /* Only clear the flag if the caller is telling us everything is
+     stopped.  */
+  else if (ptid_equal (minus_one_ptid, ptid))
+    threads_executing = 0;
+}
+
+/* See gdbthread.h.  */
+
+int
+threads_are_executing (void)
+{
+  return threads_executing;
 }
 
 void
@@ -810,7 +848,7 @@ print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
          if (!number_is_in_list (requested_threads, tp->num))
            continue;
 
-         if (pid != -1 && PIDGET (tp->ptid) != pid)
+         if (pid != -1 && ptid_get_pid (tp->ptid) != pid)
            continue;
 
          if (tp->state == THREAD_EXITED)
@@ -847,7 +885,7 @@ print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
       if (!number_is_in_list (requested_threads, tp->num))
        continue;
 
-      if (pid != -1 && PIDGET (tp->ptid) != pid)
+      if (pid != -1 && ptid_get_pid (tp->ptid) != pid)
        {
          if (requested_threads != NULL && *requested_threads != '\0')
            error (_("Requested thread not found in requested process"));
@@ -929,7 +967,7 @@ print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
          print_stack_frame (get_selected_frame (NULL),
                             /* For MI output, print frame level.  */
                             ui_out_is_mi_like_p (uiout),
-                            LOCATION);
+                            LOCATION, 0);
        }
 
       if (ui_out_is_mi_like_p (uiout))
@@ -1082,7 +1120,7 @@ restore_selected_frame (struct frame_id a_frame_id, int frame_level)
       /* For MI, we should probably have a notification about
         current frame change.  But this error is not very
         likely, so don't bother for now.  */
-      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
     }
 }
 
@@ -1243,7 +1281,7 @@ thread_apply_all_command (char *cmd, int from_tty)
       ta_cleanup.tp_array = tp_array;
       ta_cleanup.count = tc;
 
-      ALL_THREADS (tp)
+      ALL_NON_EXITED_THREADS (tp)
         {
           tp_array[i] = tp;
           tp->refcount++;
@@ -1467,7 +1505,7 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr)
   else
     {
       ui_out_text (uiout, "\n");
-      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
     }
 
   /* Since the current thread may have changed, see if there is any
@@ -1486,11 +1524,31 @@ gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
   return GDB_RC_OK;
 }
 
+/* Update the 'threads_executing' global based on the threads we know
+   about right now.  */
+
+static void
+update_threads_executing (void)
+{
+  struct thread_info *tp;
+
+  threads_executing = 0;
+  ALL_NON_EXITED_THREADS (tp)
+    {
+      if (tp->executing)
+       {
+         threads_executing = 1;
+         break;
+       }
+    }
+}
+
 void
 update_thread_list (void)
 {
   prune_threads ();
   target_find_new_threads ();
+  update_threads_executing ();
 }
 
 /* Return a new value for the selected thread's id.  Return a value of 0 if