public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*")
@ 2016-01-13 16:34 Pedro Alves
  2016-01-13 16:34 ` Pedro Alves
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-13 16:34 UTC (permalink / raw)
  To: gdb-patches

This series adds support for specifying "all threads of inferior N",
by writing "*" as thread number/range in thread ID lists.

E.g., "info threads 2.*" or "thread apply 2.* bt".

While doing this, I noticed a few bugs in "thread apply" (that even
predate the per-inferior thread IDs series).  Patch 1 fixes them.  I'm
only keeping both patches together to make it clear that patch 2
applies on top of patch 1.

Pedro Alves (2):
  Fix "thread apply $conv_var" and misc other related problems
  Star wildcard ranges (e.g., "info thread 2.*")

 gdb/NEWS                         |   6 ++
 gdb/cli/cli-utils.c              |  15 ++++
 gdb/cli/cli-utils.h              |   8 +++
 gdb/doc/gdb.texinfo              |  39 ++++++++---
 gdb/testsuite/gdb.multi/tids.exp | 143 +++++++++++++++++++++++++++++++++++----
 gdb/thread.c                     |  40 +++++++++--
 gdb/tid-parse.c                  |  63 ++++++++++++++---
 gdb/tid-parse.h                  |   7 ++
 8 files changed, 285 insertions(+), 36 deletions(-)

-- 
1.9.3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 16:34 [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
@ 2016-01-13 16:34 ` Pedro Alves
  2016-01-13 16:42   ` Pedro Alves
  2016-01-13 16:34 ` [PATCH 1/2] Fix "thread apply $conv_var" and misc other related problems Pedro Alves
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2016-01-13 16:34 UTC (permalink / raw)
  To: gdb-patches

This series adds support for specifying "all threads of inferior N",
by writing "*" as thread number/range in thread ID lists.

E.g., "info threads 2.*" or "thread apply 2.* bt".

While doing this, I noticed a few bugs in "thread apply" (that even
predate the per-inferior thread IDs series).  Patch 1 fixes them.  I'm
only keeping both patches together to make it clear that patch 2
applies on top of patch 1.

Pedro Alves (2):
  Fix "thread apply $conv_var" and misc other related problems
  Star wildcard ranges (e.g., "info thread 2.*")

 gdb/NEWS                         |   6 ++
 gdb/cli/cli-utils.c              |  15 ++++
 gdb/cli/cli-utils.h              |   8 +++
 gdb/doc/gdb.texinfo              |  39 ++++++++---
 gdb/testsuite/gdb.multi/tids.exp | 143 +++++++++++++++++++++++++++++++++++----
 gdb/thread.c                     |  40 +++++++++--
 gdb/tid-parse.c                  |  63 ++++++++++++++---
 gdb/tid-parse.h                  |   7 ++
 8 files changed, 285 insertions(+), 36 deletions(-)

-- 
1.9.3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/2] Fix "thread apply $conv_var" and misc other related problems
  2016-01-13 16:34 [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
  2016-01-13 16:34 ` Pedro Alves
@ 2016-01-13 16:34 ` Pedro Alves
  2016-01-13 16:34 ` [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-13 16:34 UTC (permalink / raw)
  To: gdb-patches

This fixes a few bugs in "thread apply".

While this works:

 (gdb) thread apply 1 p 1234

 Thread 1 (Thread 0x7ffff7fc1740 (LWP 14048)):
 $1 = 1234

This doesn't:

 (gdb) thread apply $thr p 1234

 Thread 1 (Thread 0x7ffff7fc1740 (LWP 12039)):
 Invalid thread ID: p 1234
 (gdb)

~~~~

Also, while this works:
 (gdb) thread apply 1
 Please specify a command following the thread ID list

This doesn't:
 (gdb) thread apply $thr
 Thread 1 (Thread 0x7ffff7fc1740 (LWP 12039)):
 [Current thread is 1 (Thread 0x7ffff7fc1740 (LWP 12039))]
 (gdb)

~~~~

And, while this works:
 (gdb) thread apply
 Please specify a thread ID list

This obviously bogus invocation is just silent:
 (gdb) thread apply bt
 (gdb)

gdb/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

	* thread.c (thread_apply_command): Use the tid range parser to
	advance past the thread ID list.
	* tid-parse.c (get_positive_number_trailer): New function.
	(parse_thread_id): Use it.
	(get_tid_or_range): Use it.  Return 0 instead of throwing invalid
	thread ID error.
	(get_tid_or_range): Detect negative values.  Return 0 instead of
	throwing invalid thread ID error.

gdb/testsuite/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

	* gdb.multi/tids.exp (thr_apply_info_thr_error): Remove "p 1234"
	command from "thread apply" invocation.
	(thr_apply_info_thr_invalid): Default the expected output to the
	input tid list.
	(top level): Add tests that use convenience variables.  Add tests
	for thread apply with a valid TID list, but missing the command.
---
 gdb/testsuite/gdb.multi/tids.exp | 107 ++++++++++++++++++++++++++++++++++-----
 gdb/thread.c                     |  20 ++++++--
 gdb/tid-parse.c                  |  35 ++++++++++---
 3 files changed, 139 insertions(+), 23 deletions(-)

diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp
index b72695d..28b15a3 100644
--- a/gdb/testsuite/gdb.multi/tids.exp
+++ b/gdb/testsuite/gdb.multi/tids.exp
@@ -90,7 +90,7 @@ proc thr_apply_info_thr_error {tid_list exp_error}  {
     gdb_test "info threads $tid_list" \
 	$exp_error
 
-    gdb_test "thread apply $tid_list p 1234" \
+    gdb_test "thread apply $tid_list" \
 	$exp_error \
 	"thread apply $tid_list"
 }
@@ -98,7 +98,10 @@ proc thr_apply_info_thr_error {tid_list exp_error}  {
 # Issue both "info threads TID_LIST" and "thread apply TID_LIST" and
 # expect the command to error out with "Invalid thread ID: $EXPECTED".
 # EXPECTED is a literal string, not a regexp.
-proc thr_apply_info_thr_invalid {tid_list expected} {
+proc thr_apply_info_thr_invalid {tid_list {expected ""}} {
+    if {$expected == ""} {
+	set expected $tid_list
+    }
     set expected [string_to_regexp $expected]
     gdb_test "info threads $tid_list" \
 	"Invalid thread ID: $expected"
@@ -183,6 +186,12 @@ with_test_prefix "two inferiors" {
 	gdb_continue_to_breakpoint "twice"
     }
 
+    thr_apply_info_thr "1" \
+	"1.1"
+
+    thr_apply_info_thr "1.1" \
+	"1.1"
+
     thr_apply_info_thr "1 2 3" \
 	"1.1 1.2 1.3"
 
@@ -214,6 +223,57 @@ with_test_prefix "two inferiors" {
     thr_apply_info_thr "1.1-2 2.2-3" \
 	"1.1 1.2 2.2 2.3"
 
+    # Now test using GDB convenience variables.
+
+    gdb_test "p \$inf = 1" " = 1"
+    gdb_test "p \$thr_start = 2" " = 2"
+    gdb_test "p \$thr_end = 3" " = 3"
+
+    # Convenience variable for the inferior number, only.
+    thr_apply_info_thr "\$inf.2" \
+	"1.2"
+    thr_apply_info_thr "\$inf.2-3" \
+	"1.2 1.3"
+
+    # Convenience variables for thread numbers as well.
+    foreach prefix {"" "1." "\$inf."} {
+	thr_apply_info_thr "${prefix}\$thr_start" \
+	    "1.2"
+	thr_apply_info_thr "${prefix}\$thr_start-\$thr_end" \
+	    "1.2 1.3"
+	thr_apply_info_thr "${prefix}2-\$thr_end" \
+	    "1.2 1.3"
+	thr_apply_info_thr "${prefix}\$thr_start-3" \
+	    "1.2 1.3"
+
+	# Undefined convenience variable.
+	set prefix_re [string_to_regexp $prefix]
+	thr_apply_info_thr_error "${prefix}\$conv123" \
+	    [multi_line \
+		 "Convenience variable must have integer value\." \
+		 "Invalid thread ID: ${prefix_re}\\\$conv123"]
+    }
+
+    # Convenience variables pointing at inexisting thread and/or
+    # inferior.
+    gdb_test "p \$inf = 30" " = 30"
+    gdb_test "p \$thr = 20" " = 20"
+    # Try both the convenience variable and the literal number.
+    foreach thr {"\$thr" "20" "1.20" "\$inf.1" "30.1" } {
+	set expected [string_to_regexp $thr]
+	gdb_test "info threads $thr" "No threads match '${expected}'."
+	# "info threads" works like a filter.  If there's any other
+	# valid thread in the list, there's no error.
+	info_threads "$thr 1.1" "1.1"
+	info_threads "1.1 $thr" "1.1"
+    }
+
+    gdb_test "thread apply \$thr p 1234" \
+	"warning: Unknown thread 1.20"
+
+    gdb_test "thread apply \$inf.1 p 1234" \
+	"warning: Unknown thread 30.1"
+
     # Now test a set of invalid thread IDs/ranges.
 
     thr_apply_info_thr_invalid "1." \
@@ -234,17 +294,40 @@ with_test_prefix "two inferiors" {
     thr_apply_info_thr_invalid "1-2.1" \
 	"1-2.1"
 
-    thr_apply_info_thr_error "1-0" "inverted range"
-    thr_apply_info_thr_error "1.1-0" "inverted range"
-
-    thr_apply_info_thr_error "1-" "inverted range"
-    thr_apply_info_thr_error "1.1-" "inverted range"
-
-    thr_apply_info_thr_error "2-1" "inverted range"
-    thr_apply_info_thr_error "1.2-1" "inverted range"
+    gdb_test "p \$zero = 0" " = 0"
+    gdb_test "p \$one = 1" " = 1"
+    gdb_test "p \$minus_one = -11" " = -11"
+    foreach prefix {"" "1." "$one."} {
+	set prefix_re [string_to_regexp $prefix]
+
+	thr_apply_info_thr_invalid "${prefix}foo"
+	thr_apply_info_thr_invalid "${prefix}1foo"
+	thr_apply_info_thr_invalid "${prefix}foo1"
+
+	thr_apply_info_thr_error "${prefix}1-0" "inverted range"
+	thr_apply_info_thr_error "${prefix}1-\$zero" "inverted range"
+	thr_apply_info_thr_error "${prefix}\$one-0" "inverted range"
+	thr_apply_info_thr_error "${prefix}\$one-\$zero" "inverted range"
+	thr_apply_info_thr_error "${prefix}1-" "inverted range"
+	thr_apply_info_thr_error "${prefix}2-1" "inverted range"
+	thr_apply_info_thr_error "${prefix}2-\$one" "inverted range"
+	thr_apply_info_thr_error "${prefix}-1" "negative value"
+	thr_apply_info_thr_error "${prefix}-\$one" "negative value"
+	thr_apply_info_thr_error "${prefix}\$minus_one" \
+	    "negative value: ${prefix_re}\\\$minus_one"
+    }
 
-    thr_apply_info_thr_error "-1" "negative value"
-    thr_apply_info_thr_error "1.-1" "negative value"
+    # Check that a valid thread ID list with a missing command errors
+    # out.
+    with_test_prefix "missing command" {
+	set output "Please specify a command following the thread ID list"
+	gdb_test "thread apply 1" $output
+	gdb_test "thread apply 1.1" $output
+	gdb_test "thread apply 1.1 1.2" $output
+	gdb_test "thread apply 1-2" $output
+	gdb_test "thread apply 1.1-2" $output
+	gdb_test "thread apply $thr" $output
+    }
 
     # Check that we do parse the inferior number and don't confuse it.
     gdb_test "info threads 3.1" \
diff --git a/gdb/thread.c b/gdb/thread.c
index cdd2a2f..01ce88c 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1818,19 +1818,29 @@ thread_apply_all_command (char *cmd, int from_tty)
 static void
 thread_apply_command (char *tidlist, int from_tty)
 {
-  char *cmd;
+  char *cmd = NULL;
   struct cleanup *old_chain;
   char *saved_cmd;
   struct tid_range_parser parser;
 
-  if (tidlist == NULL || *tidlist == '\000')
-    error (_("Please specify a thread ID list"));
+  tid_range_parser_init (&parser, tidlist, current_inferior ()->num);
+  while (!tid_range_parser_finished (&parser))
+    {
+      int inf_num, thr_start, thr_end;
 
-  for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
+      if (!tid_range_parser_get_tid_range (&parser, &inf_num, &thr_start, &thr_end))
+	{
+	  cmd = (char *) tid_range_parser_string (&parser);
+	  break;
+	}
+    }
 
-  if (*cmd == '\000')
+  if (cmd == NULL)
     error (_("Please specify a command following the thread ID list"));
 
+  if (tidlist == cmd || !isalpha (cmd[0]))
+    invalid_thread_id_error (cmd);
+
   /* Save a copy of the command in case it is clobbered by
      execute_command.  */
   saved_cmd = xstrdup (cmd);
diff --git a/gdb/tid-parse.c b/gdb/tid-parse.c
index 21b872d..45b7ff5 100644
--- a/gdb/tid-parse.c
+++ b/gdb/tid-parse.c
@@ -31,6 +31,23 @@ invalid_thread_id_error (const char *string)
   error (_("Invalid thread ID: %s"), string);
 }
 
+/* Wrapper for get_number_trailer that throws an error if we get back
+   a negative number.  We'll see a negative value if the number is
+   stored in a negative convenience variable (e.g., $minus_one = -1).
+   STRING is the parser string to be used in the error message if we
+   do get back a negative number.  */
+
+static int
+get_positive_number_trailer (const char **pp, int trailer, const char *string)
+{
+  int num;
+
+  num = get_number_trailer (pp, trailer);
+  if (num < 0)
+    error (_("negative value: %s"), string);
+  return num;
+}
+
 /* See tid-parse.h.  */
 
 struct thread_info *
@@ -51,7 +68,7 @@ parse_thread_id (const char *tidstr, const char **end)
       int inf_num;
 
       p1 = number;
-      inf_num = get_number_trailer (&p1, '.');
+      inf_num = get_positive_number_trailer (&p1, '.', number);
       if (inf_num == 0)
 	invalid_thread_id_error (number);
 
@@ -69,7 +86,7 @@ parse_thread_id (const char *tidstr, const char **end)
       p1 = number;
     }
 
-  thr_num = get_number_const (&p1);
+  thr_num = get_positive_number_trailer (&p1, 0, number);
   if (thr_num == 0)
     invalid_thread_id_error (number);
 
@@ -183,15 +200,16 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num,
 
 	  /* Parse number to the left of the dot.  */
 	  p = parser->string;
-	  parser->inf_num = get_number_trailer (&p, '.');
+	  parser->inf_num
+	    = get_positive_number_trailer (&p, '.', parser->string);
 	  if (parser->inf_num == 0)
-	    invalid_thread_id_error (parser->string);
+	    return 0;
 
 	  parser->qualified = 1;
 	  p = dot + 1;
 
 	  if (isspace (*p))
-	    invalid_thread_id_error (parser->string);
+	    return 0;
 	}
       else
 	{
@@ -206,8 +224,13 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num,
 
   *inf_num = parser->inf_num;
   *thr_start = get_number_or_range (&parser->range_parser);
+  if (*thr_start < 0)
+    error (_("negative value: %s"), parser->string);
   if (*thr_start == 0)
-    invalid_thread_id_error (parser->string);
+    {
+      parser->state = TID_RANGE_STATE_INFERIOR;
+      return 0;
+    }
 
   /* If we successfully parsed a thread number or finished parsing a
      thread range, switch back to assuming the next TID is
-- 
1.9.3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 16:34 [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
  2016-01-13 16:34 ` Pedro Alves
  2016-01-13 16:34 ` [PATCH 1/2] Fix "thread apply $conv_var" and misc other related problems Pedro Alves
@ 2016-01-13 16:34 ` Pedro Alves
  2016-01-13 17:00   ` Eli Zaretskii
  2016-01-14 11:29   ` Pedro Alves
  2016-01-14 16:52 ` [PATCH 0/2] " Simon Marchi
  2016-01-15 21:50 ` Pedro Alves
  4 siblings, 2 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-13 16:34 UTC (permalink / raw)
  To: gdb-patches

Add support for specifying "all threads of inferior N", by writing "*"
as thread number/range in thread ID lists.

E.g., "info threads 2.*" or "thread apply 2.* bt".

gdb/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

	* NEWS: Mention star wildcard ranges.
	* cli/cli-utils.c (number_range_setup_range): New function.
	* cli/cli-utils.h (number_range_setup_range): New declaration.
	* thread.c (thread_apply_command): Support star TID ranges.
	* tid-parse.c (tid_range_parser_finished)
	(tid_range_parser_string, tid_range_parser_skip)
	(get_tid_or_range, get_tid_or_range): Handle
	TID_RANGE_STATE_STAR_RANGE.
	(tid_range_parser_star_range): New function.
	* tid-parse.h (enum tid_range_state) <TID_RANGE_STATE_STAR_RANGE>:
	New value.
	(tid_range_parser_star_range): New declaration.

gdb/doc/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

	* gdb.texinfo (Threads) <thread ID lists>: Document star ranges.

gdb/doc/ChangeLog:
2016-01-13  Pedro Alves  <palves@redhat.com>

	* gdb.multi/tids.exp: Test star ranges.
---
 gdb/NEWS                         |  6 ++++++
 gdb/cli/cli-utils.c              | 15 +++++++++++++++
 gdb/cli/cli-utils.h              |  8 ++++++++
 gdb/doc/gdb.texinfo              | 39 +++++++++++++++++++++++++++++----------
 gdb/testsuite/gdb.multi/tids.exp | 36 ++++++++++++++++++++++++++++++++++++
 gdb/thread.c                     | 20 ++++++++++++++++++++
 gdb/tid-parse.c                  | 28 +++++++++++++++++++++++++---
 gdb/tid-parse.h                  |  7 +++++++
 8 files changed, 146 insertions(+), 13 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index d9cbb80..c00dac9 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -34,6 +34,12 @@
      [Switching to thread 2.1 (Thread 0x7ffff7fc2740 (LWP 8157))] (running)
      (gdb)
 
+* In commands that accept thread IDs lists, you can now refer to all
+  threads of an inferior using a star wildcard.  GDB accepts
+  "INF_NUM.*", to refer to all threads of inferior INF_NUM, and "*" to
+  refer to all threads of the current inferior.  For example, "info
+  threads 2.*".
+
 * You can use "info threads -gid" to display the global thread ID of
   all threads.
 
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index a68b67d..bf6ecae 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -217,6 +217,21 @@ number_is_in_list (const char *list, int number)
 
 /* See documentation in cli-utils.h.  */
 
+void
+number_range_setup_range (struct get_number_or_range_state *state,
+			  int start_value, int end_value, const char *end_ptr)
+{
+  gdb_assert (start_value > 0);
+
+  state->in_range = 1;
+  state->string = "-";
+  state->end_ptr = end_ptr;
+  state->last_retval = start_value - 1;
+  state->end_value = end_value;
+}
+
+/* See documentation in cli-utils.h.  */
+
 char *
 remove_trailing_whitespace (const char *start, char *s)
 {
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index ebf11f2..a31fff5 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -90,6 +90,14 @@ extern void init_number_or_range (struct get_number_or_range_state *state,
 
 extern int get_number_or_range (struct get_number_or_range_state *state);
 
+/* Setups STATE such that get_number_or_range returns numbers in range
+   START_VALUE to END_VALUE.  When get_number_or_range returns
+   END_VALUE, the STATE string is advanced to END_PTR.  */
+
+extern void number_range_setup_range (struct get_number_or_range_state *state,
+				      int start_value, int end_value,
+				      const char *end_ptr);
+
 /* Accept a number and a string-form list of numbers such as is 
    accepted by get_number_or_range.  Return TRUE if the number is
    in the list.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7da31c8..fbc76fa 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2912,16 +2912,35 @@ of inferior 1, the initial inferior.
 @anchor{thread ID lists}
 @cindex thread ID lists
 Some commands accept a space-separated @dfn{thread ID list} as
-argument.  A list element can be a thread ID as shown in the first
-field of the @samp{info threads} display, with or without an inferior
-qualifier (e.g., @samp{2.1} or @samp{1}); or can be a range of thread
-numbers, again with or without an inferior qualifier, as in
-@var{inf1}.@var{thr1}-@var{thr2} or @var{thr1}-@var{thr2} (e.g.,
-@samp{1.2-4} or @samp{2-4}).  For example, if the current inferior is
-1, the thread list @samp{1 2-3 4.5 6.7-9} includes threads 1 to 3 of
-inferior 1, thread 5 of inferior 4 and threads 7 to 9 of inferior 6.
-That is, in expanded qualified form, the same as @samp{1.1 1.2 1.3 4.5
-6.7 6.8 6.9}.
+argument.  A list element can be:
+
+@enumerate
+@item
+a thread ID as shown in the first field of the @samp{info threads}
+display, with or without an inferior qualifier.  E.g., @samp{2.1} or
+@samp{1}.
+
+@item
+a range of thread numbers, again with or without an inferior
+qualifier, as in @var{inf}.@var{thr1}-@var{thr2} or
+@var{thr1}-@var{thr2}.  E.g., @samp{1.2-4} or @samp{2-4}.
+
+@item
+all threads of an inferior, specified with a star wildcard, with or
+without an inferior qualifier, as in @var{inf}.@code{*} (e.g.,
+@samp{1.*}) or @code{*}.  The former refers to all threads of the
+given inferior, and the latter form without an inferior qualifier
+refers to all threads of the current inferior.
+
+@end enumerate
+
+For example, if the current inferior is 1, and inferior 7 has one
+thread with ID 7.1, the thread list @samp{1 2-3 4.5 6.7-9 7.*}
+includes threads 1 to 3 of inferior 1, thread 5 of inferior 4, threads
+7 to 9 of inferior 6 and all threads of inferior 7.  That is, in
+expanded qualified form, the same as @samp{1.1 1.2 1.3 4.5 6.7 6.8 6.9
+7.1}.
+
 
 @anchor{global thread numbers}
 @cindex global thread number
diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp
index 28b15a3..0109c10 100644
--- a/gdb/testsuite/gdb.multi/tids.exp
+++ b/gdb/testsuite/gdb.multi/tids.exp
@@ -274,6 +274,36 @@ with_test_prefix "two inferiors" {
     gdb_test "thread apply \$inf.1 p 1234" \
 	"warning: Unknown thread 30.1"
 
+    # Star ranges.
+
+    thr_apply_info_thr "1.*" \
+	"1.1 1.2 1.3"
+
+    thr_apply_info_thr "*" \
+	"1.1 1.2 1.3"
+
+    thr_apply_info_thr "1.* 2.1" \
+	"1.1 1.2 1.3 2.1"
+
+    thr_apply_info_thr "2.1 1.*" \
+	"1.1 1.2 1.3 2.1" \
+	"2.1 1.1 1.2 1.3"
+
+    thr_apply_info_thr "1.* 2.*" \
+	"1.1 1.2 1.3 2.1 2.2 2.3"
+
+    thr_apply_info_thr "2.* 1.*" \
+	"1.1 1.2 1.3 2.1 2.2 2.3" \
+	"2.1 2.2 2.3 1.1 1.2 1.3"
+
+    # There's no inferior 3, but "info threads" treats the thread list
+    # as a filter, so it's OK.  "thread apply" complains about the
+    # unknown inferior through.
+    info_threads "1.1 3.*" \
+	"1.1"
+    gdb_test "thread apply 1.1 3.* p 1" \
+	"Thread 1.1.*warning: Unknown inferior 3"
+
     # Now test a set of invalid thread IDs/ranges.
 
     thr_apply_info_thr_invalid "1." \
@@ -315,6 +345,11 @@ with_test_prefix "two inferiors" {
 	thr_apply_info_thr_error "${prefix}-\$one" "negative value"
 	thr_apply_info_thr_error "${prefix}\$minus_one" \
 	    "negative value: ${prefix_re}\\\$minus_one"
+
+	thr_apply_info_thr_error "${prefix}1-*" "inverted range"
+	thr_apply_info_thr_invalid "${prefix}*1"
+	thr_apply_info_thr_invalid "${prefix}*foo"
+	thr_apply_info_thr_invalid "${prefix}foo*"
     }
 
     # Check that a valid thread ID list with a missing command errors
@@ -327,6 +362,7 @@ with_test_prefix "two inferiors" {
 	gdb_test "thread apply 1-2" $output
 	gdb_test "thread apply 1.1-2" $output
 	gdb_test "thread apply $thr" $output
+	gdb_test "thread apply 1.*" $output
     }
 
     # Check that we do parse the inferior number and don't confuse it.
diff --git a/gdb/thread.c b/gdb/thread.c
index 01ce88c..c8f33f0 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1860,6 +1860,26 @@ thread_apply_command (char *tidlist, int from_tty)
       inf = find_inferior_id (inf_num);
       if (inf != NULL)
 	tp = find_thread_id (inf, thr_num);
+
+      if (tid_range_parser_star_range (&parser))
+	{
+	  if (inf == NULL)
+	    {
+	      warning (_("Unknown inferior %d"), inf_num);
+	      tid_range_parser_skip (&parser);
+	      continue;
+	    }
+
+	  /* No use looking for threads past the highest thread number
+	     the inferior ever had.  */
+	  if (thr_num >= inf->highest_thread_num)
+	    tid_range_parser_skip (&parser);
+
+	  /* Be quiet about unknown threads numbers.  */
+	  if (tp == NULL)
+	    continue;
+	}
+
       if (tp == NULL)
 	{
 	  if (show_inferior_qualified_tids ()
diff --git a/gdb/tid-parse.c b/gdb/tid-parse.c
index 45b7ff5..809c5fe 100644
--- a/gdb/tid-parse.c
+++ b/gdb/tid-parse.c
@@ -134,6 +134,7 @@ tid_range_parser_finished (struct tid_range_parser *parser)
     case TID_RANGE_STATE_INFERIOR:
       return *parser->string == '\0';
     case TID_RANGE_STATE_THREAD_RANGE:
+    case TID_RANGE_STATE_STAR_RANGE:
       return parser->range_parser.finished;
     }
 
@@ -150,6 +151,7 @@ tid_range_parser_string (struct tid_range_parser *parser)
     case TID_RANGE_STATE_INFERIOR:
       return parser->string;
     case TID_RANGE_STATE_THREAD_RANGE:
+    case TID_RANGE_STATE_STAR_RANGE:
       return parser->range_parser.string;
     }
 
@@ -161,7 +163,8 @@ tid_range_parser_string (struct tid_range_parser *parser)
 void
 tid_range_parser_skip (struct tid_range_parser *parser)
 {
-  gdb_assert ((parser->state == TID_RANGE_STATE_THREAD_RANGE)
+  gdb_assert ((parser->state == TID_RANGE_STATE_THREAD_RANGE
+	       || parser->state == TID_RANGE_STATE_STAR_RANGE)
 	      && parser->range_parser.in_range);
 
   tid_range_parser_init (parser, parser->range_parser.end_ptr,
@@ -219,7 +222,16 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num,
 	}
 
       init_number_or_range (&parser->range_parser, p);
-      parser->state = TID_RANGE_STATE_THREAD_RANGE;
+      if (p[0] == '*' && (p[1] == '\0' || isspace (p[1])))
+	{
+	  /* Setup the number range parser to return numbers in the
+	     whole [1,INT_MAX] range.  */
+	  number_range_setup_range (&parser->range_parser, 1, INT_MAX,
+				    skip_spaces_const (p + 1));
+	  parser->state = TID_RANGE_STATE_STAR_RANGE;
+	}
+      else
+	parser->state = TID_RANGE_STATE_THREAD_RANGE;
     }
 
   *inf_num = parser->inf_num;
@@ -247,7 +259,9 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num,
 
   /* If we're midway through a range, and the caller wants the end
      value, return it and skip to the end of the range.  */
-  if (thr_end != NULL && parser->state == TID_RANGE_STATE_THREAD_RANGE)
+  if (thr_end != NULL &&
+      (parser->state == TID_RANGE_STATE_THREAD_RANGE
+       || parser->state == TID_RANGE_STATE_STAR_RANGE))
     {
       *thr_end = parser->range_parser.end_value;
       tid_range_parser_skip (parser);
@@ -281,6 +295,14 @@ tid_range_parser_get_tid (struct tid_range_parser *parser,
 /* See tid-parse.h.  */
 
 int
+tid_range_parser_star_range (struct tid_range_parser *parser)
+{
+  return parser->state == TID_RANGE_STATE_STAR_RANGE;
+}
+
+/* See gdbthread.h.  */
+
+int
 tid_is_in_list (const char *list, int default_inferior,
 		int inf_num, int thr_num)
 {
diff --git a/gdb/tid-parse.h b/gdb/tid-parse.h
index a690edf..830cf36 100644
--- a/gdb/tid-parse.h
+++ b/gdb/tid-parse.h
@@ -44,6 +44,9 @@ enum tid_range_state
 
   /* Parsing the thread number or thread number range.  */
   TID_RANGE_STATE_THREAD_RANGE,
+
+  /* Parsing a star wildcard thread range.  E.g., "1.*".  */
+  TID_RANGE_STATE_STAR_RANGE,
 };
 
 /* An object of this type is passed to tid_range_parser_get_tid.  It
@@ -142,6 +145,10 @@ extern int tid_range_parser_get_tid_range (struct tid_range_parser *parser,
 					   int *inf_num,
 					   int *thr_start, int *thr_end);
 
+/* Returns non-zero if processing a star wildcard (e.g., "1.*")
+   range.  */
+extern int tid_range_parser_star_range (struct tid_range_parser *parser);
+
 /* Returns non-zero if parsing has completed.  */
 extern int tid_range_parser_finished (struct tid_range_parser *parser);
 
-- 
1.9.3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 16:34 ` Pedro Alves
@ 2016-01-13 16:42   ` Pedro Alves
  0 siblings, 0 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-13 16:42 UTC (permalink / raw)
  To: GDB Patches

Managed to send the cover letter as reply to the cover
letter...  Sorry about that.  The series is complete, there's
really only two patches.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 16:34 ` [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
@ 2016-01-13 17:00   ` Eli Zaretskii
  2016-01-14 11:13     ` Pedro Alves
  2016-01-14 11:29   ` Pedro Alves
  1 sibling, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2016-01-13 17:00 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

> From: Pedro Alves <palves@redhat.com>
> Date: Wed, 13 Jan 2016 16:34:45 +0000
> 
> Add support for specifying "all threads of inferior N", by writing "*"
> as thread number/range in thread ID lists.
> 
> E.g., "info threads 2.*" or "thread apply 2.* bt".

Thanks.

> +* In commands that accept thread IDs lists, you can now refer to all

"thread ID lists", only one word in plural.  Or maybe even better:
"lists of thread IDs".

> +argument.  A list element can be:
> +
> +@enumerate
> +@item
> +a thread ID as shown in the first field of the @samp{info threads}
> +display, with or without an inferior qualifier.  E.g., @samp{2.1} or
> +@samp{1}.
> +
> +@item
> +a range of thread numbers, again with or without an inferior
> +qualifier, as in @var{inf}.@var{thr1}-@var{thr2} or
> +@var{thr1}-@var{thr2}.  E.g., @samp{1.2-4} or @samp{2-4}.
> +
> +@item
> +all threads of an inferior, specified with a star wildcard, with or
> +without an inferior qualifier, as in @var{inf}.@code{*} (e.g.,
> +@samp{1.*}) or @code{*}.  The former refers to all threads of the
> +given inferior, and the latter form without an inferior qualifier
> +refers to all threads of the current inferior.

In this enumeration, each item begins with a lower-case letter, and
then continues with another sentence.  I suggest to capitalize the
first letter of each item, to be more grammatically correct.

Otherwise, the documentation parts are OK.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 17:00   ` Eli Zaretskii
@ 2016-01-14 11:13     ` Pedro Alves
  2016-01-14 16:16       ` Eli Zaretskii
  0 siblings, 1 reply; 13+ messages in thread
From: Pedro Alves @ 2016-01-14 11:13 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 01/13/2016 05:00 PM, Eli Zaretskii wrote:
>> From: Pedro Alves <palves@redhat.com>
>> Date: Wed, 13 Jan 2016 16:34:45 +0000
>>
>> Add support for specifying "all threads of inferior N", by writing "*"
>> as thread number/range in thread ID lists.
>>
>> E.g., "info threads 2.*" or "thread apply 2.* bt".
> 
> Thanks.
> 
>> +* In commands that accept thread IDs lists, you can now refer to all
> 
> "thread ID lists", only one word in plural.  Or maybe even better:
> "lists of thread IDs".

Hmm, going further, I think that "list" should be singular too:

 In commands that accept a thread ID list, you can now refer to all
 In commands that accept a list of thread IDs, you can now refer to all

I prefer the former because "thread ID list" is a defined term in
the manual.

> 
>> +argument.  A list element can be:
>> +
>> +@enumerate
>> +@item
>> +a thread ID as shown in the first field of the @samp{info threads}
>> +display, with or without an inferior qualifier.  E.g., @samp{2.1} or
>> +@samp{1}.
>> +
>> +@item
>> +a range of thread numbers, again with or without an inferior
>> +qualifier, as in @var{inf}.@var{thr1}-@var{thr2} or
>> +@var{thr1}-@var{thr2}.  E.g., @samp{1.2-4} or @samp{2-4}.
>> +
>> +@item
>> +all threads of an inferior, specified with a star wildcard, with or
>> +without an inferior qualifier, as in @var{inf}.@code{*} (e.g.,
>> +@samp{1.*}) or @code{*}.  The former refers to all threads of the
>> +given inferior, and the latter form without an inferior qualifier
>> +refers to all threads of the current inferior.
> 
> In this enumeration, each item begins with a lower-case letter, and
> then continues with another sentence.  I suggest to capitalize the
> first letter of each item, to be more grammatically correct.
> 
> Otherwise, the documentation parts are OK.

Thanks.  Here's the diff that I'm squashing in with the original version.

diff --git a/gdb/NEWS b/gdb/NEWS
index c00dac9..be3536c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -34,7 +34,7 @@
      [Switching to thread 2.1 (Thread 0x7ffff7fc2740 (LWP 8157))] (running)
      (gdb)

-* In commands that accept thread IDs lists, you can now refer to all
+* In commands that accept a thread ID list, you can now refer to all
   threads of an inferior using a star wildcard.  GDB accepts
   "INF_NUM.*", to refer to all threads of inferior INF_NUM, and "*" to
   refer to all threads of the current inferior.  For example, "info

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index fbc76fa..a08a196 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2916,17 +2916,17 @@ argument.  A list element can be:

 @enumerate
 @item
-a thread ID as shown in the first field of the @samp{info threads}
+A thread ID as shown in the first field of the @samp{info threads}
 display, with or without an inferior qualifier.  E.g., @samp{2.1} or
 @samp{1}.

 @item
-a range of thread numbers, again with or without an inferior
+A range of thread numbers, again with or without an inferior
 qualifier, as in @var{inf}.@var{thr1}-@var{thr2} or
 @var{thr1}-@var{thr2}.  E.g., @samp{1.2-4} or @samp{2-4}.

 @item
-all threads of an inferior, specified with a star wildcard, with or
+All threads of an inferior, specified with a star wildcard, with or
 without an inferior qualifier, as in @var{inf}.@code{*} (e.g.,
 @samp{1.*}) or @code{*}.  The former refers to all threads of the
 given inferior, and the latter form without an inferior qualifier
-- 
1.9.3


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 16:34 ` [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
  2016-01-13 17:00   ` Eli Zaretskii
@ 2016-01-14 11:29   ` Pedro Alves
  1 sibling, 0 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-14 11:29 UTC (permalink / raw)
  To: gdb-patches

On 01/13/2016 04:34 PM, Pedro Alves wrote:
>  
> +void
> +number_range_setup_range (struct get_number_or_range_state *state,
> +			  int start_value, int end_value, const char *end_ptr)
> +{
> +  gdb_assert (start_value > 0);
> +
> +  state->in_range = 1;
> +  state->string = "-";

I'm revisiting this "-" assignment.  This was actually a hack to make
get_number_or_range believe it is handling a range.  But, we already
have the state->in_range field for that.  It was needed because get_number_of_range
checks *state->string != '-' _before_ checking state->in_range.  But it doesn't
have to be that way -- if we swap that around, like in the hunk below, we no longer
need to hack state->string.

> +  state->end_ptr = end_ptr;
> +  state->last_retval = start_value - 1;
> +  state->end_value = end_value;
> +}

I'm squashing in this hunk with the patch, removing the hack, and reposting
a v2 series.

diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index bf6ecae..0946db0 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -134,7 +134,21 @@ init_number_or_range (struct get_number_or_range_state *state,
 int
 get_number_or_range (struct get_number_or_range_state *state)
 {
-  if (*state->string != '-')
+  if (state->in_range)
+    {
+      /* All number-parsing has already been done.  Return the next
+	 integer value (one greater than the saved previous value).
+	 Do not advance the token pointer until the end of range is
+	 reached.  */
+
+      if (++state->last_retval == state->end_value)
+	{
+	  /* End of range reached; advance token pointer.  */
+	  state->string = state->end_ptr;
+	  state->in_range = 0;
+	}
+    }
+  else if (*state->string != '-')
     {
       /* Default case: state->string is pointing either to a solo
 	 number, or to the first number of a range.  */
@@ -165,27 +179,26 @@ get_number_or_range (struct get_number_or_range_state *state)
 	    state->in_range = 1;
 	}
     }
-  else if (! state->in_range)
-    error (_("negative value"));
   else
-    {
-      /* state->string points to the '-' that betokens a range.  All
-	 number-parsing has already been done.  Return the next
-	 integer value (one greater than the saved previous value).
-	 Do not advance the token pointer until the end of range
-	 is reached.  */
-
-      if (++state->last_retval == state->end_value)
-	{
-	  /* End of range reached; advance token pointer.  */
-	  state->string = state->end_ptr;
-	  state->in_range = 0;
-	}
-    }
+    error (_("negative value"));
   state->finished = *state->string == '\0';
   return state->last_retval;
 }

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-14 11:13     ` Pedro Alves
@ 2016-01-14 16:16       ` Eli Zaretskii
  2016-01-14 16:42         ` Pedro Alves
  0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2016-01-14 16:16 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

> Date: Thu, 14 Jan 2016 11:13:47 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: gdb-patches@sourceware.org
> 
> >> +* In commands that accept thread IDs lists, you can now refer to all
> > 
> > "thread ID lists", only one word in plural.  Or maybe even better:
> > "lists of thread IDs".
> 
> Hmm, going further, I think that "list" should be singular too:
> 
>  In commands that accept a thread ID list, you can now refer to all
>  In commands that accept a list of thread IDs, you can now refer to all
> 
> I prefer the former because "thread ID list" is a defined term in
> the manual.

I won't bykeshed over it, but just so you know: use of double "status
constructus" in English is not a good style, because it is ambiguous
-- is "thread ID list" an ID list of a thread or a list of thread
IDs?  The simple "list of thread IDs" disambiguates that.

> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index fbc76fa..a08a196 100644
> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -2916,17 +2916,17 @@ argument.  A list element can be:
> 
>  @enumerate
>  @item
> -a thread ID as shown in the first field of the @samp{info threads}
> +A thread ID as shown in the first field of the @samp{info threads}
>  display, with or without an inferior qualifier.  E.g., @samp{2.1} or
>  @samp{1}.
> 
>  @item
> -a range of thread numbers, again with or without an inferior
> +A range of thread numbers, again with or without an inferior
>  qualifier, as in @var{inf}.@var{thr1}-@var{thr2} or
>  @var{thr1}-@var{thr2}.  E.g., @samp{1.2-4} or @samp{2-4}.
> 
>  @item
> -all threads of an inferior, specified with a star wildcard, with or
> +All threads of an inferior, specified with a star wildcard, with or
>  without an inferior qualifier, as in @var{inf}.@code{*} (e.g.,
>  @samp{1.*}) or @code{*}.  The former refers to all threads of the
>  given inferior, and the latter form without an inferior qualifier

Thanks, this is OK.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-14 16:16       ` Eli Zaretskii
@ 2016-01-14 16:42         ` Pedro Alves
  0 siblings, 0 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-14 16:42 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 01/14/2016 04:16 PM, Eli Zaretskii wrote:
>> Date: Thu, 14 Jan 2016 11:13:47 +0000
>> From: Pedro Alves <palves@redhat.com>
>> CC: gdb-patches@sourceware.org
>>
>>>> +* In commands that accept thread IDs lists, you can now refer to all
>>>
>>> "thread ID lists", only one word in plural.  Or maybe even better:
>>> "lists of thread IDs".
>>
>> Hmm, going further, I think that "list" should be singular too:
>>
>>  In commands that accept a thread ID list, you can now refer to all
>>  In commands that accept a list of thread IDs, you can now refer to all
>>
>> I prefer the former because "thread ID list" is a defined term in
>> the manual.
> 
> I won't bykeshed over it, but just so you know: use of double "status
> constructus" in English is not a good style, because it is ambiguous
> -- is "thread ID list" an ID list of a thread or a list of thread
> IDs?  The simple "list of thread IDs" disambiguates that.

I really don't won't to bikeshed over it either, so I'll change it,
though, I'd say that it's only ambiguous when read out of context,
and I'd argue that for the former you'd want to write
"thread's ID list".

I guess I just see it as being the same as saying "the phone number list".

> Thanks, this is OK.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 16:34 [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
                   ` (2 preceding siblings ...)
  2016-01-13 16:34 ` [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
@ 2016-01-14 16:52 ` Simon Marchi
  2016-01-15 21:50 ` Pedro Alves
  4 siblings, 0 replies; 13+ messages in thread
From: Simon Marchi @ 2016-01-14 16:52 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

On 16-01-13 11:34 AM, Pedro Alves wrote:
> This series adds support for specifying "all threads of inferior N",
> by writing "*" as thread number/range in thread ID lists.
> 
> E.g., "info threads 2.*" or "thread apply 2.* bt".
> 
> While doing this, I noticed a few bugs in "thread apply" (that even
> predate the per-inferior thread IDs series).  Patch 1 fixes them.  I'm
> only keeping both patches together to make it clear that patch 2
> applies on top of patch 1.
> 
> Pedro Alves (2):
>   Fix "thread apply $conv_var" and misc other related problems
>   Star wildcard ranges (e.g., "info thread 2.*")
> 
>  gdb/NEWS                         |   6 ++
>  gdb/cli/cli-utils.c              |  15 ++++
>  gdb/cli/cli-utils.h              |   8 +++
>  gdb/doc/gdb.texinfo              |  39 ++++++++---
>  gdb/testsuite/gdb.multi/tids.exp | 143 +++++++++++++++++++++++++++++++++++----
>  gdb/thread.c                     |  40 +++++++++--
>  gdb/tid-parse.c                  |  63 ++++++++++++++---
>  gdb/tid-parse.h                  |   7 ++
>  8 files changed, 285 insertions(+), 36 deletions(-)
> 

I took a look at those, it LGTM.  Thanks for the thorough tests.

Simon

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-13 16:34 [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
                   ` (3 preceding siblings ...)
  2016-01-14 16:52 ` [PATCH 0/2] " Simon Marchi
@ 2016-01-15 21:50 ` Pedro Alves
  4 siblings, 0 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-15 21:50 UTC (permalink / raw)
  To: GDB Patches

I've pushed this in now, with Eli's suggested NEWS tweak.

Thanks all for the review.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*")
  2016-01-14 11:39 Pedro Alves
@ 2016-01-14 11:39 ` Pedro Alves
  0 siblings, 0 replies; 13+ messages in thread
From: Pedro Alves @ 2016-01-14 11:39 UTC (permalink / raw)
  To: gdb-patches

Add support for specifying "all threads of inferior N", by writing "*"
as thread number/range in thread ID lists.

E.g., "info threads 2.*" or "thread apply 2.* bt".

gdb/ChangeLog:
2016-01-14  Pedro Alves  <palves@redhat.com>

	* NEWS: Mention star wildcard ranges.
	* cli/cli-utils.c (get_number_or_range): Check state->in_range first.
	(number_range_setup_range): New function.
	* cli/cli-utils.h (number_range_setup_range): New declaration.
	* thread.c (thread_apply_command): Support star TID ranges.
	* tid-parse.c (tid_range_parser_finished)
	(tid_range_parser_string, tid_range_parser_skip)
	(get_tid_or_range, get_tid_or_range): Handle
	TID_RANGE_STATE_STAR_RANGE.
	(tid_range_parser_star_range): New function.
	* tid-parse.h (enum tid_range_state) <TID_RANGE_STATE_STAR_RANGE>:
	New value.
	(tid_range_parser_star_range): New declaration.

gdb/doc/ChangeLog:
2016-01-14  Pedro Alves  <palves@redhat.com>

	* gdb.texinfo (Threads) <thread ID lists>: Document star ranges.

gdb/doc/ChangeLog:
2016-01-14  Pedro Alves  <palves@redhat.com>

	* gdb.multi/tids.exp: Test star ranges.
---
 gdb/NEWS                         |  6 +++++
 gdb/cli/cli-utils.c              | 47 +++++++++++++++++++++++++---------------
 gdb/cli/cli-utils.h              |  8 +++++++
 gdb/doc/gdb.texinfo              | 39 ++++++++++++++++++++++++---------
 gdb/testsuite/gdb.multi/tids.exp | 36 ++++++++++++++++++++++++++++++
 gdb/thread.c                     | 20 +++++++++++++++++
 gdb/tid-parse.c                  | 28 +++++++++++++++++++++---
 gdb/tid-parse.h                  |  7 ++++++
 8 files changed, 161 insertions(+), 30 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index d9cbb80..be3536c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -34,6 +34,12 @@
      [Switching to thread 2.1 (Thread 0x7ffff7fc2740 (LWP 8157))] (running)
      (gdb)
 
+* In commands that accept a thread ID list, you can now refer to all
+  threads of an inferior using a star wildcard.  GDB accepts
+  "INF_NUM.*", to refer to all threads of inferior INF_NUM, and "*" to
+  refer to all threads of the current inferior.  For example, "info
+  threads 2.*".
+
 * You can use "info threads -gid" to display the global thread ID of
   all threads.
 
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index a68b67d..0946db0 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -134,7 +134,21 @@ init_number_or_range (struct get_number_or_range_state *state,
 int
 get_number_or_range (struct get_number_or_range_state *state)
 {
-  if (*state->string != '-')
+  if (state->in_range)
+    {
+      /* All number-parsing has already been done.  Return the next
+	 integer value (one greater than the saved previous value).
+	 Do not advance the token pointer until the end of range is
+	 reached.  */
+
+      if (++state->last_retval == state->end_value)
+	{
+	  /* End of range reached; advance token pointer.  */
+	  state->string = state->end_ptr;
+	  state->in_range = 0;
+	}
+    }
+  else if (*state->string != '-')
     {
       /* Default case: state->string is pointing either to a solo
 	 number, or to the first number of a range.  */
@@ -165,27 +179,26 @@ get_number_or_range (struct get_number_or_range_state *state)
 	    state->in_range = 1;
 	}
     }
-  else if (! state->in_range)
-    error (_("negative value"));
   else
-    {
-      /* state->string points to the '-' that betokens a range.  All
-	 number-parsing has already been done.  Return the next
-	 integer value (one greater than the saved previous value).
-	 Do not advance the token pointer until the end of range
-	 is reached.  */
-
-      if (++state->last_retval == state->end_value)
-	{
-	  /* End of range reached; advance token pointer.  */
-	  state->string = state->end_ptr;
-	  state->in_range = 0;
-	}
-    }
+    error (_("negative value"));
   state->finished = *state->string == '\0';
   return state->last_retval;
 }
 
+/* See documentation in cli-utils.h.  */
+
+void
+number_range_setup_range (struct get_number_or_range_state *state,
+			  int start_value, int end_value, const char *end_ptr)
+{
+  gdb_assert (start_value > 0);
+
+  state->in_range = 1;
+  state->end_ptr = end_ptr;
+  state->last_retval = start_value - 1;
+  state->end_value = end_value;
+}
+
 /* Accept a number and a string-form list of numbers such as is 
    accepted by get_number_or_range.  Return TRUE if the number is
    in the list.
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index ebf11f2..a31fff5 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -90,6 +90,14 @@ extern void init_number_or_range (struct get_number_or_range_state *state,
 
 extern int get_number_or_range (struct get_number_or_range_state *state);
 
+/* Setups STATE such that get_number_or_range returns numbers in range
+   START_VALUE to END_VALUE.  When get_number_or_range returns
+   END_VALUE, the STATE string is advanced to END_PTR.  */
+
+extern void number_range_setup_range (struct get_number_or_range_state *state,
+				      int start_value, int end_value,
+				      const char *end_ptr);
+
 /* Accept a number and a string-form list of numbers such as is 
    accepted by get_number_or_range.  Return TRUE if the number is
    in the list.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7da31c8..a08a196 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2912,16 +2912,35 @@ of inferior 1, the initial inferior.
 @anchor{thread ID lists}
 @cindex thread ID lists
 Some commands accept a space-separated @dfn{thread ID list} as
-argument.  A list element can be a thread ID as shown in the first
-field of the @samp{info threads} display, with or without an inferior
-qualifier (e.g., @samp{2.1} or @samp{1}); or can be a range of thread
-numbers, again with or without an inferior qualifier, as in
-@var{inf1}.@var{thr1}-@var{thr2} or @var{thr1}-@var{thr2} (e.g.,
-@samp{1.2-4} or @samp{2-4}).  For example, if the current inferior is
-1, the thread list @samp{1 2-3 4.5 6.7-9} includes threads 1 to 3 of
-inferior 1, thread 5 of inferior 4 and threads 7 to 9 of inferior 6.
-That is, in expanded qualified form, the same as @samp{1.1 1.2 1.3 4.5
-6.7 6.8 6.9}.
+argument.  A list element can be:
+
+@enumerate
+@item
+A thread ID as shown in the first field of the @samp{info threads}
+display, with or without an inferior qualifier.  E.g., @samp{2.1} or
+@samp{1}.
+
+@item
+A range of thread numbers, again with or without an inferior
+qualifier, as in @var{inf}.@var{thr1}-@var{thr2} or
+@var{thr1}-@var{thr2}.  E.g., @samp{1.2-4} or @samp{2-4}.
+
+@item
+All threads of an inferior, specified with a star wildcard, with or
+without an inferior qualifier, as in @var{inf}.@code{*} (e.g.,
+@samp{1.*}) or @code{*}.  The former refers to all threads of the
+given inferior, and the latter form without an inferior qualifier
+refers to all threads of the current inferior.
+
+@end enumerate
+
+For example, if the current inferior is 1, and inferior 7 has one
+thread with ID 7.1, the thread list @samp{1 2-3 4.5 6.7-9 7.*}
+includes threads 1 to 3 of inferior 1, thread 5 of inferior 4, threads
+7 to 9 of inferior 6 and all threads of inferior 7.  That is, in
+expanded qualified form, the same as @samp{1.1 1.2 1.3 4.5 6.7 6.8 6.9
+7.1}.
+
 
 @anchor{global thread numbers}
 @cindex global thread number
diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp
index 28b15a3..0109c10 100644
--- a/gdb/testsuite/gdb.multi/tids.exp
+++ b/gdb/testsuite/gdb.multi/tids.exp
@@ -274,6 +274,36 @@ with_test_prefix "two inferiors" {
     gdb_test "thread apply \$inf.1 p 1234" \
 	"warning: Unknown thread 30.1"
 
+    # Star ranges.
+
+    thr_apply_info_thr "1.*" \
+	"1.1 1.2 1.3"
+
+    thr_apply_info_thr "*" \
+	"1.1 1.2 1.3"
+
+    thr_apply_info_thr "1.* 2.1" \
+	"1.1 1.2 1.3 2.1"
+
+    thr_apply_info_thr "2.1 1.*" \
+	"1.1 1.2 1.3 2.1" \
+	"2.1 1.1 1.2 1.3"
+
+    thr_apply_info_thr "1.* 2.*" \
+	"1.1 1.2 1.3 2.1 2.2 2.3"
+
+    thr_apply_info_thr "2.* 1.*" \
+	"1.1 1.2 1.3 2.1 2.2 2.3" \
+	"2.1 2.2 2.3 1.1 1.2 1.3"
+
+    # There's no inferior 3, but "info threads" treats the thread list
+    # as a filter, so it's OK.  "thread apply" complains about the
+    # unknown inferior through.
+    info_threads "1.1 3.*" \
+	"1.1"
+    gdb_test "thread apply 1.1 3.* p 1" \
+	"Thread 1.1.*warning: Unknown inferior 3"
+
     # Now test a set of invalid thread IDs/ranges.
 
     thr_apply_info_thr_invalid "1." \
@@ -315,6 +345,11 @@ with_test_prefix "two inferiors" {
 	thr_apply_info_thr_error "${prefix}-\$one" "negative value"
 	thr_apply_info_thr_error "${prefix}\$minus_one" \
 	    "negative value: ${prefix_re}\\\$minus_one"
+
+	thr_apply_info_thr_error "${prefix}1-*" "inverted range"
+	thr_apply_info_thr_invalid "${prefix}*1"
+	thr_apply_info_thr_invalid "${prefix}*foo"
+	thr_apply_info_thr_invalid "${prefix}foo*"
     }
 
     # Check that a valid thread ID list with a missing command errors
@@ -327,6 +362,7 @@ with_test_prefix "two inferiors" {
 	gdb_test "thread apply 1-2" $output
 	gdb_test "thread apply 1.1-2" $output
 	gdb_test "thread apply $thr" $output
+	gdb_test "thread apply 1.*" $output
     }
 
     # Check that we do parse the inferior number and don't confuse it.
diff --git a/gdb/thread.c b/gdb/thread.c
index f5d9cb0..ed81e55 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -1863,6 +1863,26 @@ thread_apply_command (char *tidlist, int from_tty)
       inf = find_inferior_id (inf_num);
       if (inf != NULL)
 	tp = find_thread_id (inf, thr_num);
+
+      if (tid_range_parser_star_range (&parser))
+	{
+	  if (inf == NULL)
+	    {
+	      warning (_("Unknown inferior %d"), inf_num);
+	      tid_range_parser_skip (&parser);
+	      continue;
+	    }
+
+	  /* No use looking for threads past the highest thread number
+	     the inferior ever had.  */
+	  if (thr_num >= inf->highest_thread_num)
+	    tid_range_parser_skip (&parser);
+
+	  /* Be quiet about unknown threads numbers.  */
+	  if (tp == NULL)
+	    continue;
+	}
+
       if (tp == NULL)
 	{
 	  if (show_inferior_qualified_tids ()
diff --git a/gdb/tid-parse.c b/gdb/tid-parse.c
index 45b7ff5..68133c6 100644
--- a/gdb/tid-parse.c
+++ b/gdb/tid-parse.c
@@ -134,6 +134,7 @@ tid_range_parser_finished (struct tid_range_parser *parser)
     case TID_RANGE_STATE_INFERIOR:
       return *parser->string == '\0';
     case TID_RANGE_STATE_THREAD_RANGE:
+    case TID_RANGE_STATE_STAR_RANGE:
       return parser->range_parser.finished;
     }
 
@@ -150,6 +151,7 @@ tid_range_parser_string (struct tid_range_parser *parser)
     case TID_RANGE_STATE_INFERIOR:
       return parser->string;
     case TID_RANGE_STATE_THREAD_RANGE:
+    case TID_RANGE_STATE_STAR_RANGE:
       return parser->range_parser.string;
     }
 
@@ -161,7 +163,8 @@ tid_range_parser_string (struct tid_range_parser *parser)
 void
 tid_range_parser_skip (struct tid_range_parser *parser)
 {
-  gdb_assert ((parser->state == TID_RANGE_STATE_THREAD_RANGE)
+  gdb_assert ((parser->state == TID_RANGE_STATE_THREAD_RANGE
+	       || parser->state == TID_RANGE_STATE_STAR_RANGE)
 	      && parser->range_parser.in_range);
 
   tid_range_parser_init (parser, parser->range_parser.end_ptr,
@@ -219,7 +222,16 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num,
 	}
 
       init_number_or_range (&parser->range_parser, p);
-      parser->state = TID_RANGE_STATE_THREAD_RANGE;
+      if (p[0] == '*' && (p[1] == '\0' || isspace (p[1])))
+	{
+	  /* Setup the number range parser to return numbers in the
+	     whole [1,INT_MAX] range.  */
+	  number_range_setup_range (&parser->range_parser, 1, INT_MAX,
+				    skip_spaces_const (p + 1));
+	  parser->state = TID_RANGE_STATE_STAR_RANGE;
+	}
+      else
+	parser->state = TID_RANGE_STATE_THREAD_RANGE;
     }
 
   *inf_num = parser->inf_num;
@@ -247,7 +259,9 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num,
 
   /* If we're midway through a range, and the caller wants the end
      value, return it and skip to the end of the range.  */
-  if (thr_end != NULL && parser->state == TID_RANGE_STATE_THREAD_RANGE)
+  if (thr_end != NULL
+      && (parser->state == TID_RANGE_STATE_THREAD_RANGE
+	  || parser->state == TID_RANGE_STATE_STAR_RANGE))
     {
       *thr_end = parser->range_parser.end_value;
       tid_range_parser_skip (parser);
@@ -281,6 +295,14 @@ tid_range_parser_get_tid (struct tid_range_parser *parser,
 /* See tid-parse.h.  */
 
 int
+tid_range_parser_star_range (struct tid_range_parser *parser)
+{
+  return parser->state == TID_RANGE_STATE_STAR_RANGE;
+}
+
+/* See gdbthread.h.  */
+
+int
 tid_is_in_list (const char *list, int default_inferior,
 		int inf_num, int thr_num)
 {
diff --git a/gdb/tid-parse.h b/gdb/tid-parse.h
index a690edf..830cf36 100644
--- a/gdb/tid-parse.h
+++ b/gdb/tid-parse.h
@@ -44,6 +44,9 @@ enum tid_range_state
 
   /* Parsing the thread number or thread number range.  */
   TID_RANGE_STATE_THREAD_RANGE,
+
+  /* Parsing a star wildcard thread range.  E.g., "1.*".  */
+  TID_RANGE_STATE_STAR_RANGE,
 };
 
 /* An object of this type is passed to tid_range_parser_get_tid.  It
@@ -142,6 +145,10 @@ extern int tid_range_parser_get_tid_range (struct tid_range_parser *parser,
 					   int *inf_num,
 					   int *thr_start, int *thr_end);
 
+/* Returns non-zero if processing a star wildcard (e.g., "1.*")
+   range.  */
+extern int tid_range_parser_star_range (struct tid_range_parser *parser);
+
 /* Returns non-zero if parsing has completed.  */
 extern int tid_range_parser_finished (struct tid_range_parser *parser);
 
-- 
1.9.3

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-01-15 21:50 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-13 16:34 [PATCH 0/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
2016-01-13 16:34 ` Pedro Alves
2016-01-13 16:42   ` Pedro Alves
2016-01-13 16:34 ` [PATCH 1/2] Fix "thread apply $conv_var" and misc other related problems Pedro Alves
2016-01-13 16:34 ` [PATCH 2/2] Star wildcard ranges (e.g., "info thread 2.*") Pedro Alves
2016-01-13 17:00   ` Eli Zaretskii
2016-01-14 11:13     ` Pedro Alves
2016-01-14 16:16       ` Eli Zaretskii
2016-01-14 16:42         ` Pedro Alves
2016-01-14 11:29   ` Pedro Alves
2016-01-14 16:52 ` [PATCH 0/2] " Simon Marchi
2016-01-15 21:50 ` Pedro Alves
2016-01-14 11:39 Pedro Alves
2016-01-14 11:39 ` [PATCH 2/2] " Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).