summaryrefslogtreecommitdiff
path: root/gdb/thread.c
diff options
context:
space:
mode:
authorMichael Snyder <msnyder@specifix.com>2011-02-15 21:17:51 +0000
committerMichael Snyder <msnyder@specifix.com>2011-02-15 21:17:51 +0000
commit862811ac870a3f8c35e70319fc0e566c79e4c528 (patch)
tree9e330a3c547553438cd8f242d65902bab7a07642 /gdb/thread.c
parentcfc871c10147065a34120fa6e885530b70afaa15 (diff)
downloadgdb-862811ac870a3f8c35e70319fc0e566c79e4c528.tar.gz
2011-02-15 Michael Snyder <msnyder@vmware.com>
* command.h (enum command_class): New class 'no_set_class', for "show" commands without a corresponding "set" command. * value.c (_initialize_values): Use 'no_set_class' for "show values". * copying.c (_initialize_copying): Ditto for "show copying" and "show warranty". * cli/cli-cmds.c (init_cli_cmds): Ditto for "show commands" and "show version". * cli/cli-setshow.c (cmd_show_list): Skip "show" commands for which there is no corresponding "set" command (eg. "show copying"). 2011-02-14 Michael Snyder <msnyder@vmware.com> * gdb.texinfo (threads): Document argument for "info threads" cmd. Document new command "thread find". 2011-02-15 Michael Snyder <msnyder@vmware.com> * gdb.base/default.exp: Add tests for thread commands. * gdb.base/help.exp: Add tests for thread commands. * gdb.threads/thread-find.exp: New test for thread find command.
Diffstat (limited to 'gdb/thread.c')
-rw-r--r--gdb/thread.c116
1 files changed, 108 insertions, 8 deletions
diff --git a/gdb/thread.c b/gdb/thread.c
index 62455c2a495..84691161d8c 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -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. */
@@ -954,18 +955,54 @@ No selected thread. See `help thread'.\n");
}
}
-
/* 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 = strtol (arg, &arg, 0);
+ unsigned int highrange;
+
+ if (tmp_tid <= 0)
+ error ("invalid thread id %d\n", tmp_tid);
+
+ tid = tmp_tid;
+ print_thread_info (uiout, tid, -1);
+
+ while (*arg == ' ' || *arg == '\t')
+ ++arg;
+
+ if (*arg == '-')
+ {
+ /* Do a range of threads. Must be in ascending order. */
+ ++arg; /* Skip the hyphen. */
+ highrange = strtoul (arg, &arg, 0);
+ if (highrange < tid)
+ error (_("inverted range"));
+
+ /* Do the threads in the range (first one already done). */
+ while (tid < highrange)
+ {
+ print_thread_info (uiout, ++tid, -1);
+ }
+ }
+ }
}
/* Switch from one thread to another. */
@@ -1313,6 +1350,60 @@ thread_name_command (char *arg, int from_tty)
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 +1494,11 @@ _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,
+ _("Display currently known threads.\n\
+Usage: info threads [ID]...\n\
+Optional arguments are thread IDs with spaces between.\n\
+If no arguments, all threads are displayed."));
add_prefix_cmd ("thread", class_run, thread_command, _("\
Use this command to switch between threads.\n\
@@ -1423,6 +1517,12 @@ The new thread ID must be currently known."),
Usage: thread name [NAME]\n\
If NAME is not given, then any existing name is removed."), &thread_cmd_list);
+ add_cmd ("find", class_run, thread_find_command, _("\
+Find threads that match a regular expression.\n\
+Usage: thread find REGEXP\n\
+Will display thread ids whose name, target ID, or extra info matches REGEXP."),
+ &thread_cmd_list);
+
if (!xdb_commands)
add_com_alias ("t", "thread", class_run, 1);