2002-04-24 Michael Snyder <msnyder@redhat.com>
[deliverable/binutils-gdb.git] / gdb / thread.c
index e781682ff6e63ee15412a412629b267808cdfb1f..640c4396c9bc3d993518460be7acba4b99c1c489 100644 (file)
@@ -1,9 +1,9 @@
 /* Multi-process/thread control for GDB, the GNU debugger.
-   Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
    Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.
-   
 
    This file is part of GDB.
 
 #include "command.h"
 #include "gdbcmd.h"
 #include "regcache.h"
+#include "gdb.h"
 
 #include <ctype.h>
 #include <sys/types.h>
 #include <signal.h>
-#ifdef UI_OUT
 #include "ui-out.h"
-#endif
 
 /*#include "lynxos-core.h" */
 
@@ -65,6 +64,23 @@ static void restore_current_thread (ptid_t);
 static void switch_to_thread (ptid_t ptid);
 static void prune_threads (void);
 
+void
+delete_step_resume_breakpoint (void *arg)
+{
+  struct breakpoint **breakpointp = (struct breakpoint **) arg;
+  struct thread_info *tp;
+
+  if (*breakpointp != NULL)
+    {
+      delete_breakpoint (*breakpointp);
+      for (tp = thread_list; tp; tp = tp->next)
+       if (tp->step_resume_breakpoint == *breakpointp)
+         tp->step_resume_breakpoint = NULL;
+
+      *breakpointp = NULL;
+    }
+}
+
 static void
 free_thread (struct thread_info *tp)
 {
@@ -107,26 +123,11 @@ add_thread (ptid_t ptid)
 {
   struct thread_info *tp;
 
-  tp = (struct thread_info *) xmalloc (sizeof (struct thread_info));
-
+  tp = (struct thread_info *) xmalloc (sizeof (*tp));
+  memset (tp, 0, sizeof (*tp));
   tp->ptid = ptid;
   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->stepping_through_solib_after_catch = 0;
-  tp->stepping_through_solib_catchpoints = NULL;
-  tp->stepping_through_sigtramp = 0;
   tp->next = thread_list;
-  tp->private = NULL;
   thread_list = tp;
   return tp;
 }
@@ -250,16 +251,17 @@ in_thread_list (ptid_t ptid)
 
   return 0;                    /* Never heard of 'im */
 }
-#ifdef UI_OUT
+
 /* Print a list of thread ids currently known, and the total number of
    threads. To be used from within catch_errors. */
 static int 
-do_captured_list_thread_ids (void *arg)
+do_captured_list_thread_ids (struct ui_out *uiout,
+                            void *arg)
 {
   struct thread_info *tp;
   int num = 0;
 
-  ui_out_list_begin (uiout, "thread-ids");
+  ui_out_tuple_begin (uiout, "thread-ids");
 
   for (tp = thread_list; tp; tp = tp->next)
     {
@@ -267,7 +269,7 @@ do_captured_list_thread_ids (void *arg)
       ui_out_field_int (uiout, "thread-id", tp->num);
     }
 
-  ui_out_list_end (uiout);
+  ui_out_tuple_end (uiout);
   ui_out_field_int (uiout, "number-of-threads", num);
   return GDB_RC_OK;
 }
@@ -275,25 +277,33 @@ do_captured_list_thread_ids (void *arg)
 /* Official gdblib interface function to get a list of thread ids and
    the total number. */
 enum gdb_rc
-gdb_list_thread_ids (/* output object */)
+gdb_list_thread_ids (struct ui_out *uiout)
 {
-  return catch_errors (do_captured_list_thread_ids, NULL,
-                      NULL, RETURN_MASK_ALL);
+  return catch_exceptions (uiout, do_captured_list_thread_ids, NULL,
+                          NULL, RETURN_MASK_ALL);
 }
-#endif
 
 /* Load infrun state for the thread PID.  */
 
 void
-load_infrun_state (ptid_t ptid, CORE_ADDR *prev_pc, CORE_ADDR *prev_func_start,
-                  char **prev_func_name, int *trap_expected,
+load_infrun_state (ptid_t ptid, 
+                  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, int *stepping_through_solib_after_catch,
+                  CORE_ADDR *step_range_start, 
+                  CORE_ADDR *step_range_end,
+                  CORE_ADDR *step_frame_address, 
+                  int *handling_longjmp,
+                  int *another_trap, 
+                  int *stepping_through_solib_after_catch,
                   bpstat *stepping_through_solib_catchpoints,
-                  int *stepping_through_sigtramp)
+                  int *stepping_through_sigtramp,
+                  int *current_line, 
+                  struct symtab **current_symtab, 
+                  CORE_ADDR *step_sp)
 {
   struct thread_info *tp;
 
@@ -306,31 +316,43 @@ load_infrun_state (ptid_t ptid, CORE_ADDR *prev_pc, CORE_ADDR *prev_func_start,
   *prev_pc = tp->prev_pc;
   *prev_func_start = tp->prev_func_start;
   *prev_func_name = tp->prev_func_name;
+  *trap_expected = tp->trap_expected;
   *step_resume_breakpoint = tp->step_resume_breakpoint;
+  *through_sigtramp_breakpoint = tp->through_sigtramp_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;
   *stepping_through_solib_after_catch = tp->stepping_through_solib_after_catch;
   *stepping_through_solib_catchpoints = tp->stepping_through_solib_catchpoints;
   *stepping_through_sigtramp = tp->stepping_through_sigtramp;
+  *current_line = tp->current_line;
+  *current_symtab = tp->current_symtab;
+  *step_sp = tp->step_sp;
 }
 
 /* Save infrun state for the thread PID.  */
 
 void
-save_infrun_state (ptid_t ptid, CORE_ADDR prev_pc, CORE_ADDR prev_func_start,
-                  char *prev_func_name, int trap_expected,
+save_infrun_state (ptid_t ptid, 
+                  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, int stepping_through_solib_after_catch,
+                  CORE_ADDR step_range_start, 
+                  CORE_ADDR step_range_end,
+                  CORE_ADDR step_frame_address, 
+                  int handling_longjmp,
+                  int another_trap, 
+                  int stepping_through_solib_after_catch,
                   bpstat stepping_through_solib_catchpoints,
-                  int stepping_through_sigtramp)
+                  int stepping_through_sigtramp, 
+                  int current_line,
+                  struct symtab *current_symtab,
+                  CORE_ADDR step_sp)
 {
   struct thread_info *tp;
 
@@ -343,17 +365,20 @@ save_infrun_state (ptid_t ptid, CORE_ADDR prev_pc, CORE_ADDR prev_func_start,
   tp->prev_pc = prev_pc;
   tp->prev_func_start = prev_func_start;
   tp->prev_func_name = prev_func_name;
+  tp->trap_expected = trap_expected;
   tp->step_resume_breakpoint = step_resume_breakpoint;
+  tp->through_sigtramp_breakpoint = through_sigtramp_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;
   tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
   tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
   tp->stepping_through_sigtramp = stepping_through_sigtramp;
+  tp->current_line = current_line;
+  tp->current_symtab = current_symtab;
+  tp->step_sp = step_sp;
 }
 
 /* Return true if TP is an active thread. */
@@ -396,7 +421,7 @@ info_threads_command (char *arg, int from_tty)
   struct thread_info *tp;
   ptid_t current_ptid;
   struct frame_info *cur_frame;
-  int saved_frame_level = selected_frame_level;
+  int saved_frame_level = frame_relative_level (selected_frame);
   int counter;
   char *extra_info;
 
@@ -656,11 +681,12 @@ thread_command (char *tidstr, int from_tty)
       return;
     }
 
-  gdb_thread_select (tidstr);
+  gdb_thread_select (uiout, tidstr);
 }
 
 static int
-do_captured_thread_select (void *tidstr)
+do_captured_thread_select (struct ui_out *uiout,
+                          void *tidstr)
 {
   int num;
   struct thread_info *tp;
@@ -669,21 +695,14 @@ do_captured_thread_select (void *tidstr)
 
   tp = find_thread_id (num);
 
-#ifdef UI_OUT
   if (!tp)
     error ("Thread ID %d not known.", num);
-#else
-  if (!tp)
-    error ("Thread ID %d not known.  Use the \"info threads\" command to\n\
-see the IDs of currently known threads.", num);
-#endif
 
   if (!thread_alive (tp))
     error ("Thread ID %d has terminated.\n", num);
 
   switch_to_thread (tp->ptid);
 
-#ifdef UI_OUT
   ui_out_text (uiout, "[Switching to thread ");
   ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
   ui_out_text (uiout, " (");
@@ -693,26 +712,17 @@ see the IDs of currently known threads.", num);
   ui_out_text (uiout, target_pid_to_str (inferior_ptid));
 #endif
   ui_out_text (uiout, ")]");
-#else /* UI_OUT */
-  printf_filtered ("[Switching to thread %d (%s)]\n",
-                  pid_to_thread_id (inferior_ptid),
-#if defined(HPUXHPPA)
-                  target_tid_to_str (inferior_ptid)
-#else
-                  target_pid_to_str (inferior_ptid)
-#endif
-    );
-#endif /* UI_OUT */
 
-  print_stack_frame (selected_frame, selected_frame_level, 1);
+  print_stack_frame (selected_frame, frame_relative_level (selected_frame), 1);
   return GDB_RC_OK;
 }
 
 enum gdb_rc
-gdb_thread_select (char *tidstr)
+gdb_thread_select (struct ui_out *uiout,
+                  char *tidstr)
 {
-  return catch_errors (do_captured_thread_select, tidstr,
-                      NULL, RETURN_MASK_ALL);
+  return catch_exceptions (uiout, do_captured_thread_select, tidstr,
+                          NULL, RETURN_MASK_ALL);
 }
 
 /* Commands with a prefix of `thread'.  */
This page took 0.03517 seconds and 4 git commands to generate.