Index: gdb/thread.c |
diff --git a/gdb/thread.c b/gdb/thread.c |
index ff5220df73b89e07b97d32f17fe61edf292ec978..7d889af90835a667a4620446e85087cdb9f0be88 100644 |
--- a/gdb/thread.c |
+++ b/gdb/thread.c |
@@ -1,7 +1,6 @@ |
/* Multi-process/thread control for GDB, the GNU debugger. |
- Copyright (C) 1986-1988, 1993-2004, 2007-2012 Free Software |
- Foundation, Inc. |
+ Copyright (C) 1986-2013 Free Software Foundation, Inc. |
Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. |
@@ -33,7 +32,8 @@ |
#include "gdbcmd.h" |
#include "regcache.h" |
#include "gdb.h" |
-#include "gdb_string.h" |
+#include <string.h> |
+#include "btrace.h" |
#include <ctype.h> |
#include <sys/types.h> |
@@ -65,6 +65,19 @@ static void thread_apply_command (char *, int); |
static void restore_current_thread (ptid_t); |
static void prune_threads (void); |
+/* Data to cleanup thread array. */ |
+ |
+struct thread_array_cleanup |
+{ |
+ /* Array of thread pointers used to set |
+ reference count. */ |
+ struct thread_info **tp_array; |
+ |
+ /* Thread count in the array. */ |
+ int count; |
+}; |
+ |
+ |
struct thread_info* |
inferior_thread (void) |
{ |
@@ -117,6 +130,8 @@ clear_thread_inferior_resources (struct thread_info *tp) |
bpstat_clear (&tp->control.stop_bpstat); |
+ btrace_teardown (tp); |
+ |
do_all_intermediate_continuations_thread (tp, 1); |
do_all_continuations_thread (tp, 1); |
} |
@@ -748,6 +763,13 @@ finish_thread_state_cleanup (void *arg) |
finish_thread_state (*ptid_p); |
} |
+int |
+pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread) |
+{ |
+ return (pc >= thread->control.step_range_start |
+ && pc < thread->control.step_range_end); |
+} |
+ |
/* Prints the list of threads and their details on UIOUT. |
This is a version of 'info_threads_command' suitable for |
use from MI. |
@@ -788,7 +810,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) |
@@ -825,7 +847,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")); |
@@ -907,7 +929,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)) |
@@ -987,7 +1009,6 @@ switch_to_thread (ptid_t ptid) |
inferior_ptid = ptid; |
reinit_frame_cache (); |
- registers_changed (); |
/* We don't check for is_stopped, because we're called at times |
while in the TARGET_RUNNING state, e.g., while handling an |
@@ -1056,12 +1077,12 @@ restore_selected_frame (struct frame_id a_frame_id, int frame_level) |
if (frame_level > 0 && !ui_out_is_mi_like_p (current_uiout)) |
{ |
warning (_("Couldn't restore frame #%d in " |
- "current thread, at reparsed frame #0\n"), |
+ "current thread. Bottom (innermost) frame selected:"), |
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_LINE); |
+ print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); |
} |
} |
@@ -1124,6 +1145,18 @@ restore_current_thread_cleanup_dtor (void *arg) |
xfree (old); |
} |
+/* Set the thread reference count. */ |
+ |
+static void |
+set_thread_refcount (void *data) |
+{ |
+ int k; |
+ struct thread_array_cleanup *ta_cleanup = data; |
+ |
+ for (k = 0; k != ta_cleanup->count; k++) |
+ ta_cleanup->tp_array[k]->refcount--; |
+} |
+ |
struct cleanup * |
make_cleanup_restore_current_thread (void) |
{ |
@@ -1179,9 +1212,10 @@ make_cleanup_restore_current_thread (void) |
static void |
thread_apply_all_command (char *cmd, int from_tty) |
{ |
- struct thread_info *tp; |
struct cleanup *old_chain; |
char *saved_cmd; |
+ int tc; |
+ struct thread_array_cleanup ta_cleanup; |
if (cmd == NULL || *cmd == '\000') |
error (_("Please specify a command following the thread ID list")); |
@@ -1194,17 +1228,43 @@ thread_apply_all_command (char *cmd, int from_tty) |
execute_command. */ |
saved_cmd = xstrdup (cmd); |
make_cleanup (xfree, saved_cmd); |
- for (tp = thread_list; tp; tp = tp->next) |
- if (thread_alive (tp)) |
- { |
- switch_to_thread (tp->ptid); |
+ tc = thread_count (); |
- printf_filtered (_("\nThread %d (%s):\n"), |
- tp->num, target_pid_to_str (inferior_ptid)); |
- execute_command (cmd, from_tty); |
- strcpy (cmd, saved_cmd); /* Restore exact command used |
- previously. */ |
- } |
+ if (tc) |
+ { |
+ struct thread_info **tp_array; |
+ struct thread_info *tp; |
+ int i = 0, k; |
+ |
+ /* Save a copy of the thread_list in case we execute detach |
+ command. */ |
+ tp_array = xmalloc (sizeof (struct thread_info *) * tc); |
+ make_cleanup (xfree, tp_array); |
+ ta_cleanup.tp_array = tp_array; |
+ ta_cleanup.count = tc; |
+ |
+ ALL_THREADS (tp) |
+ { |
+ tp_array[i] = tp; |
+ tp->refcount++; |
+ i++; |
+ } |
+ |
+ make_cleanup (set_thread_refcount, &ta_cleanup); |
+ |
+ for (k = 0; k != i; k++) |
+ if (thread_alive (tp_array[k])) |
+ { |
+ switch_to_thread (tp_array[k]->ptid); |
+ printf_filtered (_("\nThread %d (%s):\n"), |
+ tp_array[k]->num, |
+ target_pid_to_str (inferior_ptid)); |
+ execute_command (cmd, from_tty); |
+ |
+ /* Restore exact command used previously. */ |
+ strcpy (cmd, saved_cmd); |
+ } |
+ } |
do_cleanups (old_chain); |
} |
@@ -1235,7 +1295,6 @@ thread_apply_command (char *tidlist, int from_tty) |
{ |
struct thread_info *tp; |
int start; |
- char *p = tidlist; |
start = get_number_or_range (&state); |
@@ -1303,8 +1362,7 @@ thread_name_command (char *arg, int from_tty) |
if (ptid_equal (inferior_ptid, null_ptid)) |
error (_("No thread selected")); |
- while (arg && isspace (*arg)) |
- ++arg; |
+ arg = skip_spaces (arg); |
info = inferior_thread (); |
xfree (info->name); |
@@ -1409,7 +1467,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 |