From 054e8d9e20cf24e4b4fea6f46f289cf0475746ea Mon Sep 17 00:00:00 2001 From: Ali Anwar Date: Mon, 15 Jul 2013 11:14:32 +0000 Subject: [PATCH] 2013-07-15 Ali Anwar PR threads/13217 * thread.c (thread_apply_all_command): Check for valid threads and thread count. (thread_array_cleanup): New struct. (set_thread_refcount): New function. --- gdb/ChangeLog | 8 +++ gdb/testsuite/gdb.threads/threadapply.exp | 1 + gdb/thread.c | 74 +++++++++++++++++++---- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 383e20f62de..9da4499196f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2013-07-15 Ali Anwar + + PR threads/13217 + * thread.c (thread_apply_all_command): Check for valid threads + and thread count. + (thread_array_cleanup): New struct. + (set_thread_refcount): New function. + 2013-07-11 Andrew Burgess * infcmd.c (default_print_one_register_info): Reuse function diff --git a/gdb/testsuite/gdb.threads/threadapply.exp b/gdb/testsuite/gdb.threads/threadapply.exp index 4242904f780..5e058985ae1 100644 --- a/gdb/testsuite/gdb.threads/threadapply.exp +++ b/gdb/testsuite/gdb.threads/threadapply.exp @@ -63,3 +63,4 @@ gdb_test "step" "thread_function.*" "step to the thread_function" gdb_test "up" ".*in main.*" "go up in the stack frame" gdb_test "thread apply all print 1" "Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1" "run a simple print command on all threads" gdb_test "down" "#0.*thread_function.*" "go down and check selected frame" +gdb_test "thread apply all detach" "Thread .*" diff --git a/gdb/thread.c b/gdb/thread.c index 2eb506bb7c8..78851e462d0 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -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) { @@ -1132,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) { @@ -1187,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")); @@ -1202,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); } -- 2.30.2