Wed Nov 20 16:15:15 1996 Geoffrey Noer <noer@cygnus.com>
[deliverable/binutils-gdb.git] / gdb / thread.c
index a060beccf7c9adcc34100ecb5d2b5b6671f8d5f6..2d1826a46a588ca3ce5eac88e20809551f6d8215 100644 (file)
@@ -18,7 +18,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -27,9 +27,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "environ.h"
 #include "value.h"
 #include "target.h"
-#include "thread.h"
+#include "gdbthread.h"
 #include "command.h"
+#include "gdbcmd.h"
 
+#include <ctype.h>
 #include <sys/types.h>
 #include <signal.h>
 
@@ -40,18 +42,45 @@ struct thread_info
   struct thread_info *next;
   int pid;                     /* Actual process id */
   int num;                     /* Convenient handle */
+  CORE_ADDR prev_pc;           /* State from wait_for_inferior */
+  CORE_ADDR prev_func_start;
+  char *prev_func_name;
+  struct breakpoint *step_resume_breakpoint;
+  struct breakpoint *through_sigtramp_breakpoint;
+  CORE_ADDR step_range_start;
+  CORE_ADDR step_range_end;
+  CORE_ADDR step_frame_address;
+  int trap_expected;
+  int handling_longjmp;
+  int another_trap;
 };
 
 static struct thread_info *thread_list = NULL;
 static int highest_thread_num;
 
-static void thread_command PARAMS ((char * tidstr, int from_tty));
+static void
+thread_command PARAMS ((char * tidstr, int from_tty));
+
+static void
+prune_threads PARAMS ((void));
+
+static void
+thread_switch PARAMS ((int pid));
+
+static struct thread_info *
+find_thread_id PARAMS ((int num));
+
+static void
+info_threads_command PARAMS ((char *, int));
 
-static void prune_threads PARAMS ((void));
+static void
+restore_current_thread PARAMS ((int));
 
-static void thread_switch PARAMS ((int pid));
+static void
+thread_apply_all_command PARAMS ((char *, int));
 
-static struct thread_info * find_thread_id PARAMS ((int num));
+static void
+thread_apply_command PARAMS ((char *, int));
 
 void
 init_thread_list ()
@@ -81,6 +110,17 @@ add_thread (pid)
 
   tp->pid = pid;
   tp->num = ++highest_thread_num;
+  tp->prev_pc = 0;
+  tp->prev_func_start = 0;
+  tp->prev_func_name = NULL;
+  tp->step_range_start = 0;
+  tp->step_range_end = 0;
+  tp->step_frame_address =0;
+  tp->step_resume_breakpoint = 0;
+  tp->through_sigtramp_breakpoint = 0;
+  tp->handling_longjmp = 0;
+  tp->trap_expected = 0;
+  tp->another_trap = 0;
   tp->next = thread_list;
   thread_list = tp;
 }
@@ -137,6 +177,88 @@ in_thread_list (pid)
   return 0;                    /* Never heard of 'im */
 }
 
+/* Load infrun state for the thread PID.  */
+
+void load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
+                       trap_expected, step_resume_breakpoint,
+                       through_sigtramp_breakpoint, step_range_start,
+                       step_range_end, step_frame_address,
+                       handling_longjmp, another_trap)
+     int pid;
+     CORE_ADDR *prev_pc;
+     CORE_ADDR *prev_func_start;
+     char **prev_func_name;
+     int *trap_expected;
+     struct breakpoint **step_resume_breakpoint;
+     struct breakpoint **through_sigtramp_breakpoint;
+     CORE_ADDR *step_range_start;
+     CORE_ADDR *step_range_end;
+     CORE_ADDR *step_frame_address;
+     int *handling_longjmp;
+     int *another_trap;
+{
+  struct thread_info *tp;
+
+  /* If we can't find the thread, then we're debugging a single threaded
+     process.  No need to do anything in that case.  */
+  tp = find_thread_id (pid_to_thread_id (pid));
+  if (tp == NULL)
+    return;
+
+  *prev_pc = tp->prev_pc;
+  *prev_func_start = tp->prev_func_start;
+  *prev_func_name = tp->prev_func_name;
+  *step_resume_breakpoint = tp->step_resume_breakpoint;
+  *step_range_start = tp->step_range_start;
+  *step_range_end = tp->step_range_end;
+  *step_frame_address = tp->step_frame_address;
+  *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
+  *handling_longjmp = tp->handling_longjmp;
+  *trap_expected = tp->trap_expected;
+  *another_trap = tp->another_trap;
+}
+
+/* Save infrun state for the thread PID.  */
+
+void save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
+                       trap_expected, step_resume_breakpoint,
+                       through_sigtramp_breakpoint, step_range_start,
+                       step_range_end, step_frame_address,
+                       handling_longjmp, another_trap)
+     int pid;
+     CORE_ADDR prev_pc;
+     CORE_ADDR prev_func_start;
+     char *prev_func_name;
+     int trap_expected;
+     struct breakpoint *step_resume_breakpoint;
+     struct breakpoint *through_sigtramp_breakpoint;
+     CORE_ADDR step_range_start;
+     CORE_ADDR step_range_end;
+     CORE_ADDR step_frame_address;
+     int handling_longjmp;
+     int another_trap;
+{
+  struct thread_info *tp;
+
+  /* If we can't find the thread, then we're debugging a single-threaded
+     process.  Nothing to do in that case.  */
+  tp = find_thread_id (pid_to_thread_id (pid));
+  if (tp == NULL)
+    return;
+
+  tp->prev_pc = prev_pc;
+  tp->prev_func_start = prev_func_start;
+  tp->prev_func_name = prev_func_name;
+  tp->step_resume_breakpoint = step_resume_breakpoint;
+  tp->step_range_start = step_range_start;
+  tp->step_range_end = step_range_end;
+  tp->step_frame_address = step_frame_address;
+  tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
+  tp->handling_longjmp = handling_longjmp;
+  tp->trap_expected = trap_expected;
+  tp->another_trap = another_trap;
+}
+
 static void
 prune_threads ()
 {
@@ -168,10 +290,13 @@ info_threads_command (arg, from_tty)
   struct thread_info *tp;
   int current_pid = inferior_pid;
 
+  /* Avoid coredumps which would happen if we tried to access a NULL
+     selected_frame.  */
+  if (!target_has_stack) error ("No stack.");
+
   for (tp = thread_list; tp; tp = tp->next)
     {
-      if (target_has_execution
-         && kill (tp->pid, 0) == -1)
+      if (! target_thread_alive (tp->pid))
        {
          tp->pid = -1; /* Mark it as dead */
          continue;
@@ -205,8 +330,6 @@ thread_switch (pid)
   flush_cached_frames ();
   registers_changed ();
   stop_pc = read_pc();
-  set_current_frame (create_new_frame (read_fp (), stop_pc));
-  stop_frame_address = FRAME_FP (get_current_frame ());
   select_frame (get_current_frame (), 0);
 }
 
@@ -323,7 +446,6 @@ thread_command (tidstr, from_tty)
 {
   int num;
   struct thread_info *tp;
-  char *p;
 
   if (!tidstr)
     error ("Please specify a thread ID.  Use the \"info threads\" command to\n\
This page took 0.025799 seconds and 4 git commands to generate.