2011-02-10 Michael Snyder * thread.c (info_threads_command): Process arg as thread id, or list of thread ids. (thread_find_command): New command. (_initialize_thread): Document argument for info threads. Document 'thread find' command. Index: thread.c =================================================================== RCS file: /cvs/src/src/gdb/thread.c,v retrieving revision 1.131 diff -u -p -u -p -r1.131 thread.c --- thread.c 19 Jan 2011 17:21:36 -0000 1.131 +++ thread.c 12 Feb 2011 23:53:18 -0000 @@ -43,6 +43,7 @@ #include "observer.h" #include "annotate.h" #include "cli/cli-decode.h" +#include "gdb_regex.h" /* Definition of struct thread_info exported to gdbthread.h. */ @@ -957,15 +958,35 @@ No selected thread. See `help thread'.\ /* Print information about currently known threads - * Note: this has the drawback that it _really_ switches - * threads, which frees the frame cache. A no-side - * effects info-threads command would be nicer. - */ + Optional ARG is a thread id, or list of thread ids. + + Note: this has the drawback that it _really_ switches + threads, which frees the frame cache. A no-side + effects info-threads command would be nicer. */ static void info_threads_command (char *arg, int from_tty) { - print_thread_info (uiout, -1, -1); + int tid = -1; + + if (arg == NULL || *arg == '\0') + { + print_thread_info (uiout, -1, -1); + return; + } + + while (arg != NULL && *arg != '\0') + { + int tmp_tid + = (int) parse_and_eval_long (scan_expression_with_cleanup (&arg, + NULL)); + + if (tmp_tid != 0) + { + tid = tmp_tid; + print_thread_info (uiout, tid, -1); + } + } } /* Switch from one thread to another. */ @@ -1313,6 +1334,56 @@ thread_name_command (char *arg, int from info->name = arg ? xstrdup (arg) : NULL; } +/* Find thread ids with a name, target pid, or extra info matching ARG. */ + +static void +thread_find_command (char *arg, int from_tty) +{ + struct thread_info *tp; + char *tmp; + unsigned long match = 0; + + if (arg == NULL || *arg == '\0') + error (_("Command requires an argument.")); + + tmp = re_comp (arg); + if (tmp != 0) + error (_("Invalid regexp (%s): %s"), tmp, arg); + + update_thread_list (); + for (tp = thread_list; tp; tp = tp->next) + { + if (tp->name != NULL && re_exec (tp->name)) + { + printf_filtered ("Thread %d has name '%s'\n", tp->num, tp->name); + match++; + } + + tmp = target_thread_name (tp); + if (tmp != NULL && re_exec (tmp)) + { + printf_filtered ("Thread %d has target name '%s'\n", tp->num, tmp); + match++; + } + + tmp = target_pid_to_str (tp->ptid); + if (tmp != NULL && re_exec (tmp)) + { + printf_filtered ("Thread %d has target id '%s'\n", tp->num, tmp); + match++; + } + + tmp = target_extra_thread_info (tp); + if (tmp != NULL && re_exec (tmp)) + { + printf_filtered ("Thread %d has extra info '%s'\n", tp->num, tmp); + match++; + } + } + if (!match) + printf_filtered ("No threads match '%s'\n", arg); +} + /* Print notices when new threads are attached and detached. */ int print_thread_events = 1; static void @@ -1403,8 +1474,10 @@ _initialize_thread (void) { static struct cmd_list_element *thread_apply_list = NULL; - add_info ("threads", info_threads_command, - _("IDs of currently known threads.")); + add_info ("threads", info_threads_command, _("\ +Usage: info threads [ID [ID]...]. Display currently known threads.\n\ +If ID is given, display only that thread or those threads;\ +otherwise, all threads are displayed.")); add_prefix_cmd ("thread", class_run, thread_command, _("\ Use this command to switch between threads.\n\ @@ -1418,11 +1491,15 @@ The new thread ID must be currently know add_cmd ("all", class_run, thread_apply_all_command, _("Apply a command to all threads."), &thread_apply_list); - add_cmd ("name", class_run, thread_name_command, + add_cmd ("name", no_class, thread_name_command, _("Set the current thread's name.\n\ Usage: thread name [NAME]\n\ If NAME is not given, then any existing name is removed."), &thread_cmd_list); + add_cmd ("find", no_class, thread_find_command, _("\ +Find thread ids with a name, target pid, or extra info matching REGEXP."), + &thread_cmd_list); + if (!xdb_commands) add_com_alias ("t", "thread", class_run, 1);