gdb: make all_inferiors_safe actually work

Message ID 20210714201541.1883926-1-simon.marchi@polymtl.ca
State New
Headers show
Series
  • gdb: make all_inferiors_safe actually work
Related show

Commit Message

Simon Marchi via Gdb-patches July 14, 2021, 8:15 p.m.
The test gdb.threads/fork-plus-threads.exp fails since 08bdefb58b78
("gdb: make inferior_list use intrusive_list"):

    FAIL: gdb.threads/fork-plus-threads.exp: detach-on-fork=off: only inferior 1 left

Looking at the log, we see that we are left with a bunch of inferiors in
the detach-on-fork=off case:

    info inferiors^M
      Num  Description       Connection           Executable        ^M
    * 1    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      2    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      3    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      4    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      5    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      6    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      7    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      8    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      9    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      10   <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
      11   <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M
    (gdb) FAIL: gdb.threads/fork-plus-threads.exp: detach-on-fork=off: only inferior 1 left

when we expect to have just one.  The problem is prune_inferiors not
pruning inferiors.  And this is caused by all_inferiors_safe not
actually iterating on inferiors.  The current implementation:

  inline all_inferiors_safe_range
  all_inferiors_safe ()
  {
    return {};
  }

default-constructs an all_inferiors_safe_range, which default-constructs
an all_inferiors_safe_iterator as its m_begin field, which
default-constructs a all_inferiors_iterator.  A default-constructed
all_inferiors_iterator is an end iterator, which means we have
constructed an (end,end) all_inferiors_safe_range.

We actually need to pass down the list on which we want to iterator
(that is the inferior_list global), so that all_inferiors_iterator's
first constructor is chosen.  We also pass nullptr as the proc_target
filter.  In this case, we don't do any filtering, but if in the future
all_inferiors_safe needed to allow filtering on process target (like
all_inferiors does), we could pass down a process target pointer.

basic_safe_iterator's constructor needs to be changed to allow
constructing the wrapped iterator with multiple arguments, not just one.

With this, gdb.threads/fork-plus-threads.exp is passing once again for
me.

Change-Id: I650552ede596e3590c4b7606ce403690a0278a01
---
 gdb/inferior.h             |  2 +-
 gdbsupport/safe-iterator.h | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

-- 
2.32.0

Comments

Tom de Vries July 15, 2021, 10:15 a.m. | #1
On 7/14/21 10:15 PM, Simon Marchi wrote:
> The test gdb.threads/fork-plus-threads.exp fails since 08bdefb58b78

> ("gdb: make inferior_list use intrusive_list"):

> 

>     FAIL: gdb.threads/fork-plus-threads.exp: detach-on-fork=off: only inferior 1 left

> 

> Looking at the log, we see that we are left with a bunch of inferiors in

> the detach-on-fork=off case:

> 

>     info inferiors^M

>       Num  Description       Connection           Executable        ^M

>     * 1    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       2    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       3    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       4    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       5    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       6    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       7    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       8    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       9    <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       10   <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>       11   <null>                                 /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads ^M

>     (gdb) FAIL: gdb.threads/fork-plus-threads.exp: detach-on-fork=off: only inferior 1 left

> 

> when we expect to have just one.  The problem is prune_inferiors not

> pruning inferiors.  And this is caused by all_inferiors_safe not

> actually iterating on inferiors.  The current implementation:

> 

>   inline all_inferiors_safe_range

>   all_inferiors_safe ()

>   {

>     return {};

>   }

> 

> default-constructs an all_inferiors_safe_range, which default-constructs

> an all_inferiors_safe_iterator as its m_begin field, which

> default-constructs a all_inferiors_iterator.  A default-constructed

> all_inferiors_iterator is an end iterator, which means we have

> constructed an (end,end) all_inferiors_safe_range.

> 

> We actually need to pass down the list on which we want to iterator

> (that is the inferior_list global), so that all_inferiors_iterator's

> first constructor is chosen.  We also pass nullptr as the proc_target

> filter.  In this case, we don't do any filtering, but if in the future

> all_inferiors_safe needed to allow filtering on process target (like

> all_inferiors does), we could pass down a process target pointer.

> 

> basic_safe_iterator's constructor needs to be changed to allow

> constructing the wrapped iterator with multiple arguments, not just one.

> 

> With this, gdb.threads/fork-plus-threads.exp is passing once again for

> me.

> 


For me as well.

LGTM.

One suggestion: I'd do
s%/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads%fork-plus-threads%
in the log message for readability.

Thanks,
- Tom

> Change-Id: I650552ede596e3590c4b7606ce403690a0278a01

> ---

>  gdb/inferior.h             |  2 +-

>  gdbsupport/safe-iterator.h | 10 +++++-----

>  2 files changed, 6 insertions(+), 6 deletions(-)

> 

> diff --git a/gdb/inferior.h b/gdb/inferior.h

> index 6662a3bde463..94fbac0fc571 100644

> --- a/gdb/inferior.h

> +++ b/gdb/inferior.h

> @@ -676,7 +676,7 @@ extern intrusive_list<inferior> inferior_list;

>  inline all_inferiors_safe_range

>  all_inferiors_safe ()

>  {

> -  return {};

> +  return all_inferiors_safe_range (nullptr, inferior_list);

>  }

>  

>  /* Returns a range representing all inferiors, suitable to use with

> diff --git a/gdbsupport/safe-iterator.h b/gdbsupport/safe-iterator.h

> index 5cfc5b6ee692..53868d3b3eec 100644

> --- a/gdbsupport/safe-iterator.h

> +++ b/gdbsupport/safe-iterator.h

> @@ -48,11 +48,11 @@ class basic_safe_iterator

>    typedef typename Iterator::iterator_category iterator_category;

>    typedef typename Iterator::difference_type difference_type;

>  

> -  /* Construct using the given argument; the end iterator is default

> -     constructed.  */

> -  template<typename Arg>

> -  explicit basic_safe_iterator (Arg &&arg)

> -    : m_it (std::forward<Arg> (arg)),

> +  /* Construct the begin iterator using the given arguments; the end iterator is

> +     default constructed.  */

> +  template<typename... Args>

> +  explicit basic_safe_iterator (Args &&...args)

> +    : m_it (std::forward<Args> (args)...),

>        m_next (m_it)

>    {

>      if (m_it != m_end)

>
Simon Marchi via Gdb-patches July 17, 2021, 12:54 p.m. | #2
On 2021-07-15 6:15 a.m., Tom de Vries wrote:
> For me as well.

> 

> LGTM.

> 

> One suggestion: I'd do

> s%/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/fork-plus-threads/fork-plus-threads%fork-plus-threads%

> in the log message for readability.


Do you mean in the snippet from gdb.log I pasted?  I replaced those
with

  <snip>/fork-plus-threads

to make it clear that they were hand-edited.

Pushed with that fixed, thanks.

Simon

Patch

diff --git a/gdb/inferior.h b/gdb/inferior.h
index 6662a3bde463..94fbac0fc571 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -676,7 +676,7 @@  extern intrusive_list<inferior> inferior_list;
 inline all_inferiors_safe_range
 all_inferiors_safe ()
 {
-  return {};
+  return all_inferiors_safe_range (nullptr, inferior_list);
 }
 
 /* Returns a range representing all inferiors, suitable to use with
diff --git a/gdbsupport/safe-iterator.h b/gdbsupport/safe-iterator.h
index 5cfc5b6ee692..53868d3b3eec 100644
--- a/gdbsupport/safe-iterator.h
+++ b/gdbsupport/safe-iterator.h
@@ -48,11 +48,11 @@  class basic_safe_iterator
   typedef typename Iterator::iterator_category iterator_category;
   typedef typename Iterator::difference_type difference_type;
 
-  /* Construct using the given argument; the end iterator is default
-     constructed.  */
-  template<typename Arg>
-  explicit basic_safe_iterator (Arg &&arg)
-    : m_it (std::forward<Arg> (arg)),
+  /* Construct the begin iterator using the given arguments; the end iterator is
+     default constructed.  */
+  template<typename... Args>
+  explicit basic_safe_iterator (Args &&...args)
+    : m_it (std::forward<Args> (args)...),
       m_next (m_it)
   {
     if (m_it != m_end)