* [PATCH] gdb: new $_inferior_threads convenience variable @ 2022-11-02 14:34 Andrew Burgess 2022-11-02 14:56 ` Simon Marchi ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Andrew Burgess @ 2022-11-02 14:34 UTC (permalink / raw) To: gdb-patches; +Cc: Andrew Burgess Add a new convenience variable $_inferior_threads that contains the number of (non-exited) threads in the current inferior. This can be used in command scripts, or breakpoint conditions, etc to adjust the behaviour for multi-threaded inferiors. --- gdb/NEWS | 3 +++ gdb/doc/gdb.texinfo | 9 +++++++-- gdb/testsuite/gdb.base/default.exp | 1 + gdb/testsuite/gdb.multi/tids.exp | 20 ++++++++++++++++++++ gdb/thread.c | 25 +++++++++++++++++++++++++ gdbsupport/iterator-range.h | 4 ++++ 6 files changed, 60 insertions(+), 2 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 8b519a648f7..3642d42e55a 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -71,6 +71,9 @@ For both /r and /b GDB is now better at using whitespace in order to align the disassembled instruction text. +* New convenience variable $_inferior_threads contains the number of + non-exited threads in the current inferior. + * New commands maintenance set ignore-prologue-end-flag on|off diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index ea66f4ee42d..977cabd3771 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -3642,8 +3642,10 @@ @samp{$_gthread} contain, respectively, the per-inferior thread number and the global thread number of the current thread. You may find this useful in writing breakpoint conditional expressions, command scripts, -and so forth. @xref{Convenience Vars,, Convenience Variables}, for -general information on convenience variables. +and so forth. The convenience variable @samp{$_inferior_threads} +contains the number of non-exited threads in the current inferior. +@xref{Convenience Vars,, Convenience Variables}, for general +information on convenience variables. If @value{GDBN} detects the program is multi-threaded, it augments the usual message about stopping at a breakpoint with the ID and name of @@ -12655,6 +12657,9 @@ @item $_gthread The global number of the current thread. @xref{global thread numbers}. +@item $_inferior_threads +The number of non-exited threads in the current inferior. @xref{Threads}. + @item $_gdb_major @itemx $_gdb_minor @vindex $_gdb_major@r{, convenience variable} diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 29e76642830..cae131cc59b 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -584,6 +584,7 @@ set show_conv_list \ {$_thread = 0} \ {$_gthread = 0} \ {$_inferior = 1} \ + {$_inferior_threads = 0} \ {$_exception = <error: No frame selected>} \ {$_probe_argc = <error: No frame selected>} \ {$_probe_arg0 = <error: No frame selected>} \ diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp index fb7c2a29a71..1bcba02a1c9 100644 --- a/gdb/testsuite/gdb.multi/tids.exp +++ b/gdb/testsuite/gdb.multi/tids.exp @@ -123,6 +123,8 @@ with_test_prefix "single inferior" { info_threads "" "1" gdb_test "thread" "Current thread is 1 .*" + + gdb_test "print \$_inferior_threads" " = 1" } # "info threads" while there are multiple inferiors should show @@ -140,8 +142,14 @@ with_test_prefix "two inferiors" { gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2" gdb_test "file ${binfile}" ".*" "load file in inferior 2" + gdb_test "print \$_inferior_threads" " = 0" \ + "no threads before we start the second inferior" + runto_main + gdb_test "print \$_inferior_threads" " = 1" \ + "no other threads started yet" + # Now that we've added another inferior, thread IDs now show the # inferior number. info_threads "" "1.1 2.1" \ @@ -153,8 +161,14 @@ with_test_prefix "two inferiors" { gdb_breakpoint "thread_function1" gdb_continue_to_breakpoint "once" + gdb_test "print \$_inferior_threads" " = 2" \ + "second thread started in inferior 2" gdb_test "inferior 1" "Switching to inferior 1 .*" + gdb_test "print \$_inferior_threads" " = 1" \ + "still only one thread in inferior 1" gdb_continue_to_breakpoint "twice" + gdb_test "print \$_inferior_threads" " = 2" \ + "second thread started in inferior 1" info_threads "" "1.1 1.2 2.1 2.2" \ "info threads again" @@ -187,9 +201,15 @@ with_test_prefix "two inferiors" { gdb_test "inferior 2" "Switching to inferior 2 .*" gdb_continue_to_breakpoint "once" + gdb_test "print \$_inferior_threads" " = 3" \ + "third thread started in inferior 2" gdb_test "inferior 1" "Switching to inferior 1 .*" + gdb_test "print \$_inferior_threads" " = 2" \ + "still only two threads in inferior 1" gdb_continue_to_breakpoint "twice" + gdb_test "print \$_inferior_threads" " = 3" \ + "third thread started in inferior 1" } thr_apply_info_thr "1" \ diff --git a/gdb/thread.c b/gdb/thread.c index 349fc01dd48..f8942f1c5e4 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -2123,6 +2123,21 @@ global_thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, return thread_num_make_value_helper (gdbarch, 1); } +/* Return a new value for the number of threads in the current inferior. + If there are no threads in the current inferior return a value of 0. */ + +static struct value * +inferior_threads_make_value (struct gdbarch *gdbarch, struct internalvar *var, + void *ignore) +{ + int int_val = 0; + + if (inferior_ptid != null_ptid) + int_val = current_inferior ()->non_exited_threads ().size (); + + return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val); +} + /* Commands with a prefix of `thread'. */ struct cmd_list_element *thread_cmd_list = NULL; @@ -2142,6 +2157,14 @@ static const struct internalvar_funcs gthread_funcs = NULL, }; +/* Implementation of `_inferior_threads` convenience variable. */ + +static const struct internalvar_funcs inferior_threads_funcs = +{ + inferior_threads_make_value, + NULL, +}; + void _initialize_thread (); void _initialize_thread () @@ -2258,4 +2281,6 @@ When on messages about thread creation and deletion are printed."), create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); create_internalvar_type_lazy ("_gthread", >hread_funcs, NULL); + create_internalvar_type_lazy ("_inferior_threads", + &inferior_threads_funcs, NULL); } diff --git a/gdbsupport/iterator-range.h b/gdbsupport/iterator-range.h index d35b03a3392..c99bdc8de07 100644 --- a/gdbsupport/iterator-range.h +++ b/gdbsupport/iterator-range.h @@ -53,6 +53,10 @@ struct iterator_range IteratorType end () const { return m_end; } + /* The number of items in this iterator_range. */ + std::size_t size () const + { return std::distance (m_begin, m_end); } + private: IteratorType m_begin, m_end; }; -- 2.25.4 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] gdb: new $_inferior_threads convenience variable 2022-11-02 14:34 [PATCH] gdb: new $_inferior_threads convenience variable Andrew Burgess @ 2022-11-02 14:56 ` Simon Marchi 2022-11-02 15:07 ` Luis Machado 2022-11-03 14:42 ` [PATCHv2] gdb: new $_inferior_thread_count " Andrew Burgess 2 siblings, 0 replies; 7+ messages in thread From: Simon Marchi @ 2022-11-02 14:56 UTC (permalink / raw) To: Andrew Burgess, gdb-patches On 11/2/22 10:34, Andrew Burgess via Gdb-patches wrote: > Add a new convenience variable $_inferior_threads that contains the > number of (non-exited) threads in the current inferior. This can be > used in command scripts, or breakpoint conditions, etc to adjust the > behaviour for multi-threaded inferiors. I don't really have time to look at the code, but here's a naming nit: I think the name should contain "number" or "count" or something like that. The name "_inferior_threads" makes me think it yields a list of threads, somehow. Simon ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] gdb: new $_inferior_threads convenience variable 2022-11-02 14:34 [PATCH] gdb: new $_inferior_threads convenience variable Andrew Burgess 2022-11-02 14:56 ` Simon Marchi @ 2022-11-02 15:07 ` Luis Machado 2022-11-03 14:42 ` [PATCHv2] gdb: new $_inferior_thread_count " Andrew Burgess 2 siblings, 0 replies; 7+ messages in thread From: Luis Machado @ 2022-11-02 15:07 UTC (permalink / raw) To: Andrew Burgess, gdb-patches On 11/2/22 14:34, Andrew Burgess via Gdb-patches wrote: > Add a new convenience variable $_inferior_threads that contains the > number of (non-exited) threads in the current inferior. This can be Just a couple comments. Should we call them "live" threads instead of non-exited? > used in command scripts, or breakpoint conditions, etc to adjust the > behaviour for multi-threaded inferiors. Could this number be a bit misleading at times? For example, a nonstop debugging session with threads coming and going and everything running. I'm guessing the number wouldn't be reliable enough to walk some list, right? > --- > gdb/NEWS | 3 +++ > gdb/doc/gdb.texinfo | 9 +++++++-- > gdb/testsuite/gdb.base/default.exp | 1 + > gdb/testsuite/gdb.multi/tids.exp | 20 ++++++++++++++++++++ > gdb/thread.c | 25 +++++++++++++++++++++++++ > gdbsupport/iterator-range.h | 4 ++++ > 6 files changed, 60 insertions(+), 2 deletions(-) > > diff --git a/gdb/NEWS b/gdb/NEWS > index 8b519a648f7..3642d42e55a 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -71,6 +71,9 @@ > For both /r and /b GDB is now better at using whitespace in order to > align the disassembled instruction text. > > +* New convenience variable $_inferior_threads contains the number of > + non-exited threads in the current inferior. > + > * New commands > > maintenance set ignore-prologue-end-flag on|off > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index ea66f4ee42d..977cabd3771 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -3642,8 +3642,10 @@ > @samp{$_gthread} contain, respectively, the per-inferior thread number > and the global thread number of the current thread. You may find this > useful in writing breakpoint conditional expressions, command scripts, > -and so forth. @xref{Convenience Vars,, Convenience Variables}, for > -general information on convenience variables. > +and so forth. The convenience variable @samp{$_inferior_threads} > +contains the number of non-exited threads in the current inferior. > +@xref{Convenience Vars,, Convenience Variables}, for general > +information on convenience variables. > > If @value{GDBN} detects the program is multi-threaded, it augments the > usual message about stopping at a breakpoint with the ID and name of > @@ -12655,6 +12657,9 @@ > @item $_gthread > The global number of the current thread. @xref{global thread numbers}. > > +@item $_inferior_threads > +The number of non-exited threads in the current inferior. @xref{Threads}. > + > @item $_gdb_major > @itemx $_gdb_minor > @vindex $_gdb_major@r{, convenience variable} > diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp > index 29e76642830..cae131cc59b 100644 > --- a/gdb/testsuite/gdb.base/default.exp > +++ b/gdb/testsuite/gdb.base/default.exp > @@ -584,6 +584,7 @@ set show_conv_list \ > {$_thread = 0} \ > {$_gthread = 0} \ > {$_inferior = 1} \ > + {$_inferior_threads = 0} \ > {$_exception = <error: No frame selected>} \ > {$_probe_argc = <error: No frame selected>} \ > {$_probe_arg0 = <error: No frame selected>} \ > diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp > index fb7c2a29a71..1bcba02a1c9 100644 > --- a/gdb/testsuite/gdb.multi/tids.exp > +++ b/gdb/testsuite/gdb.multi/tids.exp > @@ -123,6 +123,8 @@ with_test_prefix "single inferior" { > info_threads "" "1" > > gdb_test "thread" "Current thread is 1 .*" > + > + gdb_test "print \$_inferior_threads" " = 1" > } > > # "info threads" while there are multiple inferiors should show > @@ -140,8 +142,14 @@ with_test_prefix "two inferiors" { > gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2" > gdb_test "file ${binfile}" ".*" "load file in inferior 2" > > + gdb_test "print \$_inferior_threads" " = 0" \ > + "no threads before we start the second inferior" > + > runto_main > > + gdb_test "print \$_inferior_threads" " = 1" \ > + "no other threads started yet" > + > # Now that we've added another inferior, thread IDs now show the > # inferior number. > info_threads "" "1.1 2.1" \ > @@ -153,8 +161,14 @@ with_test_prefix "two inferiors" { > gdb_breakpoint "thread_function1" > > gdb_continue_to_breakpoint "once" > + gdb_test "print \$_inferior_threads" " = 2" \ > + "second thread started in inferior 2" > gdb_test "inferior 1" "Switching to inferior 1 .*" > + gdb_test "print \$_inferior_threads" " = 1" \ > + "still only one thread in inferior 1" > gdb_continue_to_breakpoint "twice" > + gdb_test "print \$_inferior_threads" " = 2" \ > + "second thread started in inferior 1" > > info_threads "" "1.1 1.2 2.1 2.2" \ > "info threads again" > @@ -187,9 +201,15 @@ with_test_prefix "two inferiors" { > > gdb_test "inferior 2" "Switching to inferior 2 .*" > gdb_continue_to_breakpoint "once" > + gdb_test "print \$_inferior_threads" " = 3" \ > + "third thread started in inferior 2" > > gdb_test "inferior 1" "Switching to inferior 1 .*" > + gdb_test "print \$_inferior_threads" " = 2" \ > + "still only two threads in inferior 1" > gdb_continue_to_breakpoint "twice" > + gdb_test "print \$_inferior_threads" " = 3" \ > + "third thread started in inferior 1" > } > > thr_apply_info_thr "1" \ > diff --git a/gdb/thread.c b/gdb/thread.c > index 349fc01dd48..f8942f1c5e4 100644 > --- a/gdb/thread.c > +++ b/gdb/thread.c > @@ -2123,6 +2123,21 @@ global_thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, > return thread_num_make_value_helper (gdbarch, 1); > } > > +/* Return a new value for the number of threads in the current inferior. > + If there are no threads in the current inferior return a value of 0. */ > + > +static struct value * > +inferior_threads_make_value (struct gdbarch *gdbarch, struct internalvar *var, > + void *ignore) > +{ > + int int_val = 0; > + > + if (inferior_ptid != null_ptid) > + int_val = current_inferior ()->non_exited_threads ().size (); > + > + return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val); > +} > + > /* Commands with a prefix of `thread'. */ > struct cmd_list_element *thread_cmd_list = NULL; > > @@ -2142,6 +2157,14 @@ static const struct internalvar_funcs gthread_funcs = > NULL, > }; > > +/* Implementation of `_inferior_threads` convenience variable. */ > + > +static const struct internalvar_funcs inferior_threads_funcs = > +{ > + inferior_threads_make_value, > + NULL, > +}; > + > void _initialize_thread (); > void > _initialize_thread () > @@ -2258,4 +2281,6 @@ When on messages about thread creation and deletion are printed."), > > create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); > create_internalvar_type_lazy ("_gthread", >hread_funcs, NULL); > + create_internalvar_type_lazy ("_inferior_threads", > + &inferior_threads_funcs, NULL); > } > diff --git a/gdbsupport/iterator-range.h b/gdbsupport/iterator-range.h > index d35b03a3392..c99bdc8de07 100644 > --- a/gdbsupport/iterator-range.h > +++ b/gdbsupport/iterator-range.h > @@ -53,6 +53,10 @@ struct iterator_range > IteratorType end () const > { return m_end; } > > + /* The number of items in this iterator_range. */ > + std::size_t size () const > + { return std::distance (m_begin, m_end); } > + > private: > IteratorType m_begin, m_end; > }; ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCHv2] gdb: new $_inferior_thread_count convenience variable 2022-11-02 14:34 [PATCH] gdb: new $_inferior_threads convenience variable Andrew Burgess 2022-11-02 14:56 ` Simon Marchi 2022-11-02 15:07 ` Luis Machado @ 2022-11-03 14:42 ` Andrew Burgess 2022-11-03 14:48 ` Eli Zaretskii ` (2 more replies) 2 siblings, 3 replies; 7+ messages in thread From: Andrew Burgess @ 2022-11-03 14:42 UTC (permalink / raw) To: gdb-patches; +Cc: Andrew Burgess Simon, Luis, thanks for your feedback. Changes since v1: 1. Rename variable to $_inferior_thread_count. 2. Use "live" in the docs and NEWS file to describe the threads being counted. I do still use "non-exited" within the commit message and comments, as this is how "live" is actually implemented within GDB. 3. Updated the docs to mention that in non-stop mode the value of $_inferior_thread_count will not be stable. Thanks, Andrew --- Add a new convenience variable $_inferior_thread_count that contains the number of live (non-exited) threads in the current inferior. This can be used in command scripts, or breakpoint conditions, etc to adjust the behaviour for multi-threaded inferiors. This value is only stable in all-stop mode. In non-stop mode, where new threads can be started, and existing threads exit, at any time, this convenience variable can give a different value each time it is evaluated. --- gdb/NEWS | 3 +++ gdb/doc/gdb.texinfo | 14 ++++++++++++-- gdb/testsuite/gdb.base/default.exp | 1 + gdb/testsuite/gdb.multi/tids.exp | 20 ++++++++++++++++++++ gdb/thread.c | 26 ++++++++++++++++++++++++++ gdbsupport/iterator-range.h | 4 ++++ 6 files changed, 66 insertions(+), 2 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 8b519a648f7..8857dedb8b8 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -71,6 +71,9 @@ For both /r and /b GDB is now better at using whitespace in order to align the disassembled instruction text. +* New convenience variable $_inferior_thread_count contains the number + of live threads in the current inferior. + * New commands maintenance set ignore-prologue-end-flag on|off diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index ea66f4ee42d..82f7fd66bf0 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -3642,8 +3642,15 @@ @samp{$_gthread} contain, respectively, the per-inferior thread number and the global thread number of the current thread. You may find this useful in writing breakpoint conditional expressions, command scripts, -and so forth. @xref{Convenience Vars,, Convenience Variables}, for -general information on convenience variables. +and so forth. The convenience variable @samp{$_inferior_thread_count} +contains the number of live threads in the current inferior. +@xref{Convenience Vars,, Convenience Variables}, for general +information on convenience variables. + +When running in non-stop mode (@pxref{Non-Stop Mode}), where new +threads can be created, and existing threads exit, at any time, +@samp{$_inferior_thread_count} could return a different value each +time it is evaluated. If @value{GDBN} detects the program is multi-threaded, it augments the usual message about stopping at a breakpoint with the ID and name of @@ -12655,6 +12662,9 @@ @item $_gthread The global number of the current thread. @xref{global thread numbers}. +@item $_inferior_thread_count +The number of live threads in the current inferior. @xref{Threads}. + @item $_gdb_major @itemx $_gdb_minor @vindex $_gdb_major@r{, convenience variable} diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp index 29e76642830..f3e4b2867ef 100644 --- a/gdb/testsuite/gdb.base/default.exp +++ b/gdb/testsuite/gdb.base/default.exp @@ -584,6 +584,7 @@ set show_conv_list \ {$_thread = 0} \ {$_gthread = 0} \ {$_inferior = 1} \ + {$_inferior_thread_count = 0} \ {$_exception = <error: No frame selected>} \ {$_probe_argc = <error: No frame selected>} \ {$_probe_arg0 = <error: No frame selected>} \ diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp index fb7c2a29a71..23668caf18f 100644 --- a/gdb/testsuite/gdb.multi/tids.exp +++ b/gdb/testsuite/gdb.multi/tids.exp @@ -123,6 +123,8 @@ with_test_prefix "single inferior" { info_threads "" "1" gdb_test "thread" "Current thread is 1 .*" + + gdb_test "print \$_inferior_thread_count" " = 1" } # "info threads" while there are multiple inferiors should show @@ -140,8 +142,14 @@ with_test_prefix "two inferiors" { gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2" gdb_test "file ${binfile}" ".*" "load file in inferior 2" + gdb_test "print \$_inferior_thread_count" " = 0" \ + "no threads before we start the second inferior" + runto_main + gdb_test "print \$_inferior_thread_count" " = 1" \ + "no other threads started yet" + # Now that we've added another inferior, thread IDs now show the # inferior number. info_threads "" "1.1 2.1" \ @@ -153,8 +161,14 @@ with_test_prefix "two inferiors" { gdb_breakpoint "thread_function1" gdb_continue_to_breakpoint "once" + gdb_test "print \$_inferior_thread_count" " = 2" \ + "second thread started in inferior 2" gdb_test "inferior 1" "Switching to inferior 1 .*" + gdb_test "print \$_inferior_thread_count" " = 1" \ + "still only one thread in inferior 1" gdb_continue_to_breakpoint "twice" + gdb_test "print \$_inferior_thread_count" " = 2" \ + "second thread started in inferior 1" info_threads "" "1.1 1.2 2.1 2.2" \ "info threads again" @@ -187,9 +201,15 @@ with_test_prefix "two inferiors" { gdb_test "inferior 2" "Switching to inferior 2 .*" gdb_continue_to_breakpoint "once" + gdb_test "print \$_inferior_thread_count" " = 3" \ + "third thread started in inferior 2" gdb_test "inferior 1" "Switching to inferior 1 .*" + gdb_test "print \$_inferior_thread_count" " = 2" \ + "still only two threads in inferior 1" gdb_continue_to_breakpoint "twice" + gdb_test "print \$_inferior_thread_count" " = 3" \ + "third thread started in inferior 1" } thr_apply_info_thr "1" \ diff --git a/gdb/thread.c b/gdb/thread.c index 349fc01dd48..d176d1d9895 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -2123,6 +2123,22 @@ global_thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, return thread_num_make_value_helper (gdbarch, 1); } +/* Return a new value for the number of non-exited threads in the current + inferior. If there are no threads in the current inferior return a + value of 0. */ + +static struct value * +inferior_thread_count_make_value (struct gdbarch *gdbarch, + struct internalvar *var, void *ignore) +{ + int int_val = 0; + + if (inferior_ptid != null_ptid) + int_val = current_inferior ()->non_exited_threads ().size (); + + return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val); +} + /* Commands with a prefix of `thread'. */ struct cmd_list_element *thread_cmd_list = NULL; @@ -2142,6 +2158,14 @@ static const struct internalvar_funcs gthread_funcs = NULL, }; +/* Implementation of `_inferior_thread_count` convenience variable. */ + +static const struct internalvar_funcs inferior_thread_count_funcs = +{ + inferior_thread_count_make_value, + NULL, +}; + void _initialize_thread (); void _initialize_thread () @@ -2258,4 +2282,6 @@ When on messages about thread creation and deletion are printed."), create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); create_internalvar_type_lazy ("_gthread", >hread_funcs, NULL); + create_internalvar_type_lazy ("_inferior_thread_count", + &inferior_thread_count_funcs, NULL); } diff --git a/gdbsupport/iterator-range.h b/gdbsupport/iterator-range.h index d35b03a3392..c99bdc8de07 100644 --- a/gdbsupport/iterator-range.h +++ b/gdbsupport/iterator-range.h @@ -53,6 +53,10 @@ struct iterator_range IteratorType end () const { return m_end; } + /* The number of items in this iterator_range. */ + std::size_t size () const + { return std::distance (m_begin, m_end); } + private: IteratorType m_begin, m_end; }; -- 2.25.4 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCHv2] gdb: new $_inferior_thread_count convenience variable 2022-11-03 14:42 ` [PATCHv2] gdb: new $_inferior_thread_count " Andrew Burgess @ 2022-11-03 14:48 ` Eli Zaretskii 2022-11-03 15:03 ` Luis Machado 2022-11-17 14:51 ` Andrew Burgess 2 siblings, 0 replies; 7+ messages in thread From: Eli Zaretskii @ 2022-11-03 14:48 UTC (permalink / raw) To: Andrew Burgess; +Cc: gdb-patches > Date: Thu, 3 Nov 2022 14:42:39 +0000 > From: Andrew Burgess via Gdb-patches <gdb-patches@sourceware.org> > > gdb/NEWS | 3 +++ > gdb/doc/gdb.texinfo | 14 ++++++++++++-- > gdb/testsuite/gdb.base/default.exp | 1 + > gdb/testsuite/gdb.multi/tids.exp | 20 ++++++++++++++++++++ > gdb/thread.c | 26 ++++++++++++++++++++++++++ > gdbsupport/iterator-range.h | 4 ++++ > 6 files changed, 66 insertions(+), 2 deletions(-) OK for the documentation parts, thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCHv2] gdb: new $_inferior_thread_count convenience variable 2022-11-03 14:42 ` [PATCHv2] gdb: new $_inferior_thread_count " Andrew Burgess 2022-11-03 14:48 ` Eli Zaretskii @ 2022-11-03 15:03 ` Luis Machado 2022-11-17 14:51 ` Andrew Burgess 2 siblings, 0 replies; 7+ messages in thread From: Luis Machado @ 2022-11-03 15:03 UTC (permalink / raw) To: Andrew Burgess, gdb-patches On 11/3/22 14:42, Andrew Burgess via Gdb-patches wrote: > Simon, Luis, thanks for your feedback. > > Changes since v1: > > 1. Rename variable to $_inferior_thread_count. > > 2. Use "live" in the docs and NEWS file to describe the threads > being counted. I do still use "non-exited" within the commit > message and comments, as this is how "live" is actually implemented > within GDB. > > 3. Updated the docs to mention that in non-stop mode the value of > $_inferior_thread_count will not be stable. > > Thanks, > Andrew > > --- > > Add a new convenience variable $_inferior_thread_count that contains > the number of live (non-exited) threads in the current inferior. This > can be used in command scripts, or breakpoint conditions, etc to > adjust the behaviour for multi-threaded inferiors. > > This value is only stable in all-stop mode. In non-stop mode, where > new threads can be started, and existing threads exit, at any time, > this convenience variable can give a different value each time it is > evaluated. > --- > gdb/NEWS | 3 +++ > gdb/doc/gdb.texinfo | 14 ++++++++++++-- > gdb/testsuite/gdb.base/default.exp | 1 + > gdb/testsuite/gdb.multi/tids.exp | 20 ++++++++++++++++++++ > gdb/thread.c | 26 ++++++++++++++++++++++++++ > gdbsupport/iterator-range.h | 4 ++++ > 6 files changed, 66 insertions(+), 2 deletions(-) > > diff --git a/gdb/NEWS b/gdb/NEWS > index 8b519a648f7..8857dedb8b8 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -71,6 +71,9 @@ > For both /r and /b GDB is now better at using whitespace in order to > align the disassembled instruction text. > > +* New convenience variable $_inferior_thread_count contains the number > + of live threads in the current inferior. > + > * New commands > > maintenance set ignore-prologue-end-flag on|off > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index ea66f4ee42d..82f7fd66bf0 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -3642,8 +3642,15 @@ > @samp{$_gthread} contain, respectively, the per-inferior thread number > and the global thread number of the current thread. You may find this > useful in writing breakpoint conditional expressions, command scripts, > -and so forth. @xref{Convenience Vars,, Convenience Variables}, for > -general information on convenience variables. > +and so forth. The convenience variable @samp{$_inferior_thread_count} > +contains the number of live threads in the current inferior. > +@xref{Convenience Vars,, Convenience Variables}, for general > +information on convenience variables. > + > +When running in non-stop mode (@pxref{Non-Stop Mode}), where new > +threads can be created, and existing threads exit, at any time, > +@samp{$_inferior_thread_count} could return a different value each > +time it is evaluated. > > If @value{GDBN} detects the program is multi-threaded, it augments the > usual message about stopping at a breakpoint with the ID and name of > @@ -12655,6 +12662,9 @@ > @item $_gthread > The global number of the current thread. @xref{global thread numbers}. > > +@item $_inferior_thread_count > +The number of live threads in the current inferior. @xref{Threads}. > + > @item $_gdb_major > @itemx $_gdb_minor > @vindex $_gdb_major@r{, convenience variable} > diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp > index 29e76642830..f3e4b2867ef 100644 > --- a/gdb/testsuite/gdb.base/default.exp > +++ b/gdb/testsuite/gdb.base/default.exp > @@ -584,6 +584,7 @@ set show_conv_list \ > {$_thread = 0} \ > {$_gthread = 0} \ > {$_inferior = 1} \ > + {$_inferior_thread_count = 0} \ > {$_exception = <error: No frame selected>} \ > {$_probe_argc = <error: No frame selected>} \ > {$_probe_arg0 = <error: No frame selected>} \ > diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp > index fb7c2a29a71..23668caf18f 100644 > --- a/gdb/testsuite/gdb.multi/tids.exp > +++ b/gdb/testsuite/gdb.multi/tids.exp > @@ -123,6 +123,8 @@ with_test_prefix "single inferior" { > info_threads "" "1" > > gdb_test "thread" "Current thread is 1 .*" > + > + gdb_test "print \$_inferior_thread_count" " = 1" > } > > # "info threads" while there are multiple inferiors should show > @@ -140,8 +142,14 @@ with_test_prefix "two inferiors" { > gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2" > gdb_test "file ${binfile}" ".*" "load file in inferior 2" > > + gdb_test "print \$_inferior_thread_count" " = 0" \ > + "no threads before we start the second inferior" > + > runto_main > > + gdb_test "print \$_inferior_thread_count" " = 1" \ > + "no other threads started yet" > + > # Now that we've added another inferior, thread IDs now show the > # inferior number. > info_threads "" "1.1 2.1" \ > @@ -153,8 +161,14 @@ with_test_prefix "two inferiors" { > gdb_breakpoint "thread_function1" > > gdb_continue_to_breakpoint "once" > + gdb_test "print \$_inferior_thread_count" " = 2" \ > + "second thread started in inferior 2" > gdb_test "inferior 1" "Switching to inferior 1 .*" > + gdb_test "print \$_inferior_thread_count" " = 1" \ > + "still only one thread in inferior 1" > gdb_continue_to_breakpoint "twice" > + gdb_test "print \$_inferior_thread_count" " = 2" \ > + "second thread started in inferior 1" > > info_threads "" "1.1 1.2 2.1 2.2" \ > "info threads again" > @@ -187,9 +201,15 @@ with_test_prefix "two inferiors" { > > gdb_test "inferior 2" "Switching to inferior 2 .*" > gdb_continue_to_breakpoint "once" > + gdb_test "print \$_inferior_thread_count" " = 3" \ > + "third thread started in inferior 2" > > gdb_test "inferior 1" "Switching to inferior 1 .*" > + gdb_test "print \$_inferior_thread_count" " = 2" \ > + "still only two threads in inferior 1" > gdb_continue_to_breakpoint "twice" > + gdb_test "print \$_inferior_thread_count" " = 3" \ > + "third thread started in inferior 1" > } > > thr_apply_info_thr "1" \ > diff --git a/gdb/thread.c b/gdb/thread.c > index 349fc01dd48..d176d1d9895 100644 > --- a/gdb/thread.c > +++ b/gdb/thread.c > @@ -2123,6 +2123,22 @@ global_thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, > return thread_num_make_value_helper (gdbarch, 1); > } > > +/* Return a new value for the number of non-exited threads in the current > + inferior. If there are no threads in the current inferior return a > + value of 0. */ > + > +static struct value * > +inferior_thread_count_make_value (struct gdbarch *gdbarch, > + struct internalvar *var, void *ignore) > +{ > + int int_val = 0; > + > + if (inferior_ptid != null_ptid) > + int_val = current_inferior ()->non_exited_threads ().size (); > + > + return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val); > +} > + > /* Commands with a prefix of `thread'. */ > struct cmd_list_element *thread_cmd_list = NULL; > > @@ -2142,6 +2158,14 @@ static const struct internalvar_funcs gthread_funcs = > NULL, > }; > > +/* Implementation of `_inferior_thread_count` convenience variable. */ > + > +static const struct internalvar_funcs inferior_thread_count_funcs = > +{ > + inferior_thread_count_make_value, > + NULL, > +}; > + > void _initialize_thread (); > void > _initialize_thread () > @@ -2258,4 +2282,6 @@ When on messages about thread creation and deletion are printed."), > > create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); > create_internalvar_type_lazy ("_gthread", >hread_funcs, NULL); > + create_internalvar_type_lazy ("_inferior_thread_count", > + &inferior_thread_count_funcs, NULL); > } > diff --git a/gdbsupport/iterator-range.h b/gdbsupport/iterator-range.h > index d35b03a3392..c99bdc8de07 100644 > --- a/gdbsupport/iterator-range.h > +++ b/gdbsupport/iterator-range.h > @@ -53,6 +53,10 @@ struct iterator_range > IteratorType end () const > { return m_end; } > > + /* The number of items in this iterator_range. */ > + std::size_t size () const > + { return std::distance (m_begin, m_end); } > + > private: > IteratorType m_begin, m_end; > }; LGTM. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCHv2] gdb: new $_inferior_thread_count convenience variable 2022-11-03 14:42 ` [PATCHv2] gdb: new $_inferior_thread_count " Andrew Burgess 2022-11-03 14:48 ` Eli Zaretskii 2022-11-03 15:03 ` Luis Machado @ 2022-11-17 14:51 ` Andrew Burgess 2 siblings, 0 replies; 7+ messages in thread From: Andrew Burgess @ 2022-11-17 14:51 UTC (permalink / raw) To: gdb-patches Andrew Burgess <aburgess@redhat.com> writes: > Simon, Luis, thanks for your feedback. > > Changes since v1: > > 1. Rename variable to $_inferior_thread_count. > > 2. Use "live" in the docs and NEWS file to describe the threads > being counted. I do still use "non-exited" within the commit > message and comments, as this is how "live" is actually implemented > within GDB. > > 3. Updated the docs to mention that in non-stop mode the value of > $_inferior_thread_count will not be stable. Thanks for the reviews. I've pushed this patch. Andrew > > Thanks, > Andrew > > --- > > Add a new convenience variable $_inferior_thread_count that contains > the number of live (non-exited) threads in the current inferior. This > can be used in command scripts, or breakpoint conditions, etc to > adjust the behaviour for multi-threaded inferiors. > > This value is only stable in all-stop mode. In non-stop mode, where > new threads can be started, and existing threads exit, at any time, > this convenience variable can give a different value each time it is > evaluated. > --- > gdb/NEWS | 3 +++ > gdb/doc/gdb.texinfo | 14 ++++++++++++-- > gdb/testsuite/gdb.base/default.exp | 1 + > gdb/testsuite/gdb.multi/tids.exp | 20 ++++++++++++++++++++ > gdb/thread.c | 26 ++++++++++++++++++++++++++ > gdbsupport/iterator-range.h | 4 ++++ > 6 files changed, 66 insertions(+), 2 deletions(-) > > diff --git a/gdb/NEWS b/gdb/NEWS > index 8b519a648f7..8857dedb8b8 100644 > --- a/gdb/NEWS > +++ b/gdb/NEWS > @@ -71,6 +71,9 @@ > For both /r and /b GDB is now better at using whitespace in order to > align the disassembled instruction text. > > +* New convenience variable $_inferior_thread_count contains the number > + of live threads in the current inferior. > + > * New commands > > maintenance set ignore-prologue-end-flag on|off > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index ea66f4ee42d..82f7fd66bf0 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -3642,8 +3642,15 @@ > @samp{$_gthread} contain, respectively, the per-inferior thread number > and the global thread number of the current thread. You may find this > useful in writing breakpoint conditional expressions, command scripts, > -and so forth. @xref{Convenience Vars,, Convenience Variables}, for > -general information on convenience variables. > +and so forth. The convenience variable @samp{$_inferior_thread_count} > +contains the number of live threads in the current inferior. > +@xref{Convenience Vars,, Convenience Variables}, for general > +information on convenience variables. > + > +When running in non-stop mode (@pxref{Non-Stop Mode}), where new > +threads can be created, and existing threads exit, at any time, > +@samp{$_inferior_thread_count} could return a different value each > +time it is evaluated. > > If @value{GDBN} detects the program is multi-threaded, it augments the > usual message about stopping at a breakpoint with the ID and name of > @@ -12655,6 +12662,9 @@ > @item $_gthread > The global number of the current thread. @xref{global thread numbers}. > > +@item $_inferior_thread_count > +The number of live threads in the current inferior. @xref{Threads}. > + > @item $_gdb_major > @itemx $_gdb_minor > @vindex $_gdb_major@r{, convenience variable} > diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp > index 29e76642830..f3e4b2867ef 100644 > --- a/gdb/testsuite/gdb.base/default.exp > +++ b/gdb/testsuite/gdb.base/default.exp > @@ -584,6 +584,7 @@ set show_conv_list \ > {$_thread = 0} \ > {$_gthread = 0} \ > {$_inferior = 1} \ > + {$_inferior_thread_count = 0} \ > {$_exception = <error: No frame selected>} \ > {$_probe_argc = <error: No frame selected>} \ > {$_probe_arg0 = <error: No frame selected>} \ > diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp > index fb7c2a29a71..23668caf18f 100644 > --- a/gdb/testsuite/gdb.multi/tids.exp > +++ b/gdb/testsuite/gdb.multi/tids.exp > @@ -123,6 +123,8 @@ with_test_prefix "single inferior" { > info_threads "" "1" > > gdb_test "thread" "Current thread is 1 .*" > + > + gdb_test "print \$_inferior_thread_count" " = 1" > } > > # "info threads" while there are multiple inferiors should show > @@ -140,8 +142,14 @@ with_test_prefix "two inferiors" { > gdb_test "inferior 2" "Switching to inferior 2 .*" "switch to inferior 2" > gdb_test "file ${binfile}" ".*" "load file in inferior 2" > > + gdb_test "print \$_inferior_thread_count" " = 0" \ > + "no threads before we start the second inferior" > + > runto_main > > + gdb_test "print \$_inferior_thread_count" " = 1" \ > + "no other threads started yet" > + > # Now that we've added another inferior, thread IDs now show the > # inferior number. > info_threads "" "1.1 2.1" \ > @@ -153,8 +161,14 @@ with_test_prefix "two inferiors" { > gdb_breakpoint "thread_function1" > > gdb_continue_to_breakpoint "once" > + gdb_test "print \$_inferior_thread_count" " = 2" \ > + "second thread started in inferior 2" > gdb_test "inferior 1" "Switching to inferior 1 .*" > + gdb_test "print \$_inferior_thread_count" " = 1" \ > + "still only one thread in inferior 1" > gdb_continue_to_breakpoint "twice" > + gdb_test "print \$_inferior_thread_count" " = 2" \ > + "second thread started in inferior 1" > > info_threads "" "1.1 1.2 2.1 2.2" \ > "info threads again" > @@ -187,9 +201,15 @@ with_test_prefix "two inferiors" { > > gdb_test "inferior 2" "Switching to inferior 2 .*" > gdb_continue_to_breakpoint "once" > + gdb_test "print \$_inferior_thread_count" " = 3" \ > + "third thread started in inferior 2" > > gdb_test "inferior 1" "Switching to inferior 1 .*" > + gdb_test "print \$_inferior_thread_count" " = 2" \ > + "still only two threads in inferior 1" > gdb_continue_to_breakpoint "twice" > + gdb_test "print \$_inferior_thread_count" " = 3" \ > + "third thread started in inferior 1" > } > > thr_apply_info_thr "1" \ > diff --git a/gdb/thread.c b/gdb/thread.c > index 349fc01dd48..d176d1d9895 100644 > --- a/gdb/thread.c > +++ b/gdb/thread.c > @@ -2123,6 +2123,22 @@ global_thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var, > return thread_num_make_value_helper (gdbarch, 1); > } > > +/* Return a new value for the number of non-exited threads in the current > + inferior. If there are no threads in the current inferior return a > + value of 0. */ > + > +static struct value * > +inferior_thread_count_make_value (struct gdbarch *gdbarch, > + struct internalvar *var, void *ignore) > +{ > + int int_val = 0; > + > + if (inferior_ptid != null_ptid) > + int_val = current_inferior ()->non_exited_threads ().size (); > + > + return value_from_longest (builtin_type (gdbarch)->builtin_int, int_val); > +} > + > /* Commands with a prefix of `thread'. */ > struct cmd_list_element *thread_cmd_list = NULL; > > @@ -2142,6 +2158,14 @@ static const struct internalvar_funcs gthread_funcs = > NULL, > }; > > +/* Implementation of `_inferior_thread_count` convenience variable. */ > + > +static const struct internalvar_funcs inferior_thread_count_funcs = > +{ > + inferior_thread_count_make_value, > + NULL, > +}; > + > void _initialize_thread (); > void > _initialize_thread () > @@ -2258,4 +2282,6 @@ When on messages about thread creation and deletion are printed."), > > create_internalvar_type_lazy ("_thread", &thread_funcs, NULL); > create_internalvar_type_lazy ("_gthread", >hread_funcs, NULL); > + create_internalvar_type_lazy ("_inferior_thread_count", > + &inferior_thread_count_funcs, NULL); > } > diff --git a/gdbsupport/iterator-range.h b/gdbsupport/iterator-range.h > index d35b03a3392..c99bdc8de07 100644 > --- a/gdbsupport/iterator-range.h > +++ b/gdbsupport/iterator-range.h > @@ -53,6 +53,10 @@ struct iterator_range > IteratorType end () const > { return m_end; } > > + /* The number of items in this iterator_range. */ > + std::size_t size () const > + { return std::distance (m_begin, m_end); } > + > private: > IteratorType m_begin, m_end; > }; > -- > 2.25.4 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2022-11-17 14:51 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-11-02 14:34 [PATCH] gdb: new $_inferior_threads convenience variable Andrew Burgess 2022-11-02 14:56 ` Simon Marchi 2022-11-02 15:07 ` Luis Machado 2022-11-03 14:42 ` [PATCHv2] gdb: new $_inferior_thread_count " Andrew Burgess 2022-11-03 14:48 ` Eli Zaretskii 2022-11-03 15:03 ` Luis Machado 2022-11-17 14:51 ` Andrew Burgess
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).