Bug 28180 - FAIL: gdb.ada/interface.exp: print s (timeout)
Summary: FAIL: gdb.ada/interface.exp: print s (timeout)
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: ada (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 12.1
Assignee: Tom Tromey
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-08-02 22:32 UTC by Tom de Vries
Modified: 2024-03-08 09:55 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
foo.gz (213.67 KB, application/gzip)
2021-08-05 15:04 UTC, Tom de Vries
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2021-08-02 22:32:28 UTC
With current master I noticed this timeout:
...
(gdb) PASS: gdb.ada/interface.exp: print r
print s^M
Multiple matches for s^M
[0] cancel^M
[1] s at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/interface/foo.adb:20^M
[2] s at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/interface/foo.adb:?^M
> FAIL: gdb.ada/interface.exp: print s (timeout)
...

Bisects to:
...
commit ba8694b650b60c29126fd958575ffa1ca4f6c415 (HEAD)
Author: Tom Tromey <tromey@adacore.com>
Date:   Thu Jul 1 08:55:15 2021 -0600

    Handle type qualifier for enumeration name
    
    Pierre-Marie noticed that the Ada expression "TYPE'(NAME)" resolved
    incorrectly when "TYPE" was an enumeration type.  Here, "NAME" should
    be unambiguous.
    
    This patch fixes this problem.  Note that the patch is not perfect --
    it does not give an error if TYPE is an enumeration type but NAME is
    not an enumerator but does have some other meaning in scope.  Fixing
    this proved difficult, and so I've left it out.
...

Fails with gcc-7.5.0, 8.5.0, passes with gcc-9.3.1, gcc-10.3.1, gcc-11.1.1.
Comment 1 Tom de Vries 2021-08-02 22:36:39 UTC
Same for:
...
(gdb) PASS: gdb.ada/tagged.exp: print segm
ptype obj^M
Multiple matches for obj^M
[0] cancel^M
[1] obj at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/tagged/foo.adb:20^M
[2] obj at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/tagged/foo.adb:?^M
> FAIL: gdb.ada/tagged.exp: ptype obj (timeout)
...
Comment 2 Tom Tromey 2021-08-04 20:06:42 UTC
(In reply to Tom de Vries from comment #0)

> [1] s at
> /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/
> interface/foo.adb:20^M
> [2] s at
> /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/
> interface/foo.adb:?^M

The second location is pretty weird.
I suspect this is just some kind of debuginfo problem
with the older compiler.

> Same for:
> ...
> > FAIL: gdb.ada/tagged.exp: ptype obj (timeout)

Is it the same compiler versions that fail here?
I can't test it readily but I can send a patch to disable
these tests with an older gcc.
Comment 3 Tom de Vries 2021-08-05 10:11:13 UTC
(In reply to Tom de Vries from comment #0)
> With current master I noticed this timeout:
> ...
> (gdb) PASS: gdb.ada/interface.exp: print r
> print s^M
> Multiple matches for s^M
> [0] cancel^M
> [1] s at
> /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/
> interface/foo.adb:20^M
> [2] s at
> /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/
> interface/foo.adb:?^M
> > FAIL: gdb.ada/interface.exp: print s (timeout)
> ...

Doing a bit of investigation, we see:
...
Breakpoint 1, foo () at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/interface/foo.adb:22
22         Do_Nothing (R);  -- STOP
(gdb) info locals
r = (x => 1, y => 2, w => 3, h => 4)
<G6b_LAST> = 8
<foo__G6b___U> = 8
s = (x => 1, y => 2, w => 3, h => 4)
s = 0x7fffffffd890
...

So both "s" are local variables.

That makes it easy to find in the dwarf.

We have:
...
 <2><1204>: Abbrev Number: 31 (DW_TAG_variable)
    <1205>   DW_AT_name        : (indirect string, offset: 0x13e6): s.14
    <1209>   DW_AT_type        : <0x1213>
    <120d>   DW_AT_artificial  : 1
    <120d>   DW_AT_location    : 5 byte block: 91 e0 7d 23 18   (DW_OP_fbreg: -288; DW_OP_plus_uconst: 24)
...
and:
...
 <3><1249>: Abbrev Number: 33 (DW_TAG_variable) 
    <124a>   DW_AT_name        : s
    <124c>   DW_AT_decl_file   : 1
    <124d>   DW_AT_decl_line   : 20
    <124e>   DW_AT_type        : <0x146d>
    <1252>   DW_AT_location    : 6 byte block: 91 e0 7d 23 18 6         (DW_OP_fbreg: -288; DW_OP_plus_uconst: 24; DW_OP_deref)
...

I suppose the first is the unexpected one.  It has DW_AT_artificial, but is still put into the symbol table because it has a DW_AT_name.

This patch:
...
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index acabee3315f..44327ecbd9a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -21585,6 +21585,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_
cu *cu,
   if (name)
     {
       int suppress_add = 0;
+      attr = dwarf2_attr (die, DW_AT_artificial, cu);
+      if (attr != nullptr)
+       suppress_add = 1;
 
       if (space)
        sym = space;
...
gets us:
...
$ gdb -q -batch  outputs/gdb.ada/interface/foo -ex "b foo.adb:22" -ex r -ex "p s"
Breakpoint 1 at 0x404455: file foo.adb, line 22.

Breakpoint 1, foo () at foo.adb:22
22         Do_Nothing (R);  -- STOP
warning: Unknown upper bound, using 1.
$1 = (x => 1, y => 2, w => 3, h => 4)
...
but with the warning because foo__G6b___U (which is another artificial variable) cannot be evaluated.

Hmm, so ada uses named artifical variables that need to be in the symbol table in order to evaluate them, but they should be ignored in terms of gdb commands that investigate source constructs like "p s".  That seems to be the root cause.
Comment 4 Tom de Vries 2021-08-05 10:56:55 UTC
This allows the test-case to pass:
...
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 6680a4fd657..e3bfcd8aa9f 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -3539,6 +3539,16 @@ ada_resolve_variable (struct symbol *sym, const struct block *block,

         candidates.end ());
     }
 
+  candidates.erase
+    (std::remove_if
+     (candidates.begin (),
+      candidates.end (),
+      [] (block_symbol &bsym)
+      {
+       return bsym.symbol->artificial;
+      }),
+     candidates.end ());
+
   int i;
   if (candidates.empty ())
     error (_("No definition found for %s"), sym->print_name ());
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index acabee3315f..bff615d31ee 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -21592,6 +21592,10 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2
_cu *cu,
        sym = new (&objfile->objfile_obstack) symbol;
       OBJSTAT (objfile, n_syms++);
 
+      attr = dwarf2_attr (die, DW_AT_artificial, cu);
+      if (attr != nullptr)
+       sym->artificial = 1;
+
       /* Cache this symbol's name and the name's demangled form (if any).  */
       sym->set_language (cu->per_cu->lang, &objfile->objfile_obstack);
       /* Fortran does not have mangling standard and the mangling does differ
diff --git a/gdb/symtab.h b/gdb/symtab.h
index fd8dd62a406..b028586e50f 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -536,6 +536,8 @@ struct general_symbol_info
      valid.  */
   unsigned int ada_mangled : 1;
 
+  unsigned int artificial : 1;
+
   /* Which section is this symbol in?  This is an index into
      section_offsets for this objfile.  Negative means that the symbol
      does not get relocated relative to a section.  */
@@ -1131,6 +1133,7 @@ struct symbol : public general_symbol_info, public allocate_on_obstac
k
       language_specific.obstack = nullptr;
       m_language = language_unknown;
       ada_mangled = 0;
+      artificial = 0;
       m_section = -1;
       /* GCC 4.8.5 (on CentOS 7) does not correctly compile class-
         initialization of unions, so we initialize it manually here.  */
...
and passes gdb.ada/*.exp.
Comment 5 Tom de Vries 2021-08-05 13:03:01 UTC
(In reply to Tom de Vries from comment #0)
> Fails with gcc-7.5.0, 8.5.0, passes with gcc-9.3.1, gcc-10.3.1, gcc-11.1.1.

Which bisects to:
...
commit d70ba0c10dec6968d178303709204fdde3d8892f (refs/bisect/bad)
Author: Eric Botcazou <ebotcazou@adacore.com>
Date:   Sun Jun 17 11:36:58 2018 +0000

    gimplify.c (nonlocal_vlas): Delete.
...
submitted here ( https://gcc.gnu.org/pipermail/gcc-patches/2018-June/500683.html ).
Comment 6 Tom de Vries 2021-08-05 13:17:00 UTC
(In reply to Tom Tromey from comment #2)
> (In reply to Tom de Vries from comment #0)
> 
> > [1] s at
> > /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/
> > interface/foo.adb:20^M
> > [2] s at
> > /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/
> > interface/foo.adb:?^M
> 
> The second location is pretty weird.

AFAICT, due to the corresponding artificial variable in dwarf having no location info.

> I suspect this is just some kind of debuginfo problem
> with the older compiler.
> 

I cannot tell whether the change in debug info is incorrect -> correct, or just different.

Either way, the patch from comment 4 seems to be able to handle this.

> > Same for:
> > ...
> > > FAIL: gdb.ada/tagged.exp: ptype obj (timeout)
> 
> Is it the same compiler versions that fail here?

Yes.

> I can't test it readily but I can send a patch to disable
> these tests with an older gcc.

Any thoughts on the patch ?
Comment 7 Tom de Vries 2021-08-05 15:04:39 UTC
Created attachment 13594 [details]
foo.gz

Reproduce:
...
$ gunzip foo.gz 
$ gdb -q -batch ./foo -ex "b foo.adb:22" -ex r -ex "p s"
Breakpoint 1 at 0x404455: file /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/interface/foo.adb, line 22.

Breakpoint 1, foo () at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/interface/foo.adb:22
22         Do_Nothing (R);  -- STOP
Multiple matches for s
[0] cancel
[1] s at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/interface/foo.adb:20
[2] s at /home/vries/gdb_versions/devel/binutils-gdb.git/gdb/testsuite/gdb.ada/interface/foo.adb:?
> 
...
Comment 8 Tom Tromey 2021-08-06 16:16:36 UTC
(In reply to Tom de Vries from comment #3)

> Hmm, so ada uses named artifical variables that need to be in the symbol
> table in order to evaluate them, but they should be ignored in terms of gdb
> commands that investigate source constructs like "p s".  That seems to be
> the root cause.

Yeah, Ada uses a special setup where some debug info is expressed via
magic symbol names.  The Ada compiler is moving away from this --
gcc recently switched its default to "minimal encodings", but even with
this in place there are still some things that require this treatment.


> Any thoughts on the patch ?

Unless there's some strong need, my inclination would be to not do anything
special to support older versions of the compiler.  We're trying to move
everything to "real DWARF", at least to the extent that this is possible.

Joel is away right now, but I'll CC him to see what he thinks.
Comment 9 Tom de Vries 2021-08-08 08:35:33 UTC
(In reply to Tom Tromey from comment #8)
> (In reply to Tom de Vries from comment #3)
> 
> > Hmm, so ada uses named artifical variables that need to be in the symbol
> > table in order to evaluate them, but they should be ignored in terms of gdb
> > commands that investigate source constructs like "p s".  That seems to be
> > the root cause.
> 
> Yeah, Ada uses a special setup where some debug info is expressed via
> magic symbol names.  The Ada compiler is moving away from this --
> gcc recently switched its default to "minimal encodings", but even with
> this in place there are still some things that require this treatment.
> 
> 
> > Any thoughts on the patch ?
> 
> Unless there's some strong need, my inclination would be to not do anything
> special to support older versions of the compiler.  We're trying to move
> everything to "real DWARF", at least to the extent that this is possible.
> 
> Joel is away right now, but I'll CC him to see what he thinks.

FTR, I can live with an xfail.  But it's good to note that with the latest gcc version, the compiler still produces this type of variables (not s.14, but others, f.i. <G6b_LAST>), and an xfail should explain why s.14 is incorrect compiler output, and <G6b_LAST> correct compiler output.
Comment 10 Tom Tromey 2021-08-13 18:42:54 UTC
(In reply to Tom de Vries from comment #4)
> This allows the test-case to pass:
> ...

I was digging through local code recently and I found out that AdaCore
has a patch that does something along these lines.
There's a function:

/* Return non-zero if STR should be suppressed in info listings.  */

static int
is_suppressed_name (const char *str)


then a macro that ends up calling that:

#define SYMBOL_PRINTING_SUPPRESSED(symbol)				\
  (current_language->la_language == language_ada			\
   && ada_suppress_symbol_printing (symbol))


Then iterate_over_block_locals does:

  ALL_BLOCK_SYMBOLS (b, iter, sym)
    {
      if (SYMBOL_PRINTING_SUPPRESSED (sym))
	continue;

This code dates to 2007; I don't know if it's ever been sent upstream.

I'm building gcc 8 to see if I can reproduce this.
Maybe the answer is your patch after all, or maybe upstreaming this local one.
Comment 11 Tom Tromey 2021-08-13 18:53:37 UTC
> I'm building gcc 8 to see if I can reproduce this.

Well, I couldn't build it on this machine,
so I'm not sure what to do now.
If I package up the local change, could you try it out?
Comment 12 Tom de Vries 2021-08-14 13:13:08 UTC
(In reply to Tom Tromey from comment #11)
> > I'm building gcc 8 to see if I can reproduce this.
> 
> Well, I couldn't build it on this machine,
> so I'm not sure what to do now.
> If I package up the local change, could you try it out?

Sure. [ Though I'm on vacation now, so limited to ubuntu 18.04.5, and possibly not able to do a quick response. ]
Comment 13 Tom de Vries 2021-08-14 14:36:28 UTC
(In reply to Tom Tromey from comment #10)
> This code dates to 2007; I don't know if it's ever been sent upstream.
> 

Perhaps https://sourceware.org/pipermail/gdb-patches/2008-January/054994.html
?
Comment 14 Joel Brobecker 2021-08-17 18:05:34 UTC
> Perhaps https://sourceware.org/pipermail/gdb-patches/2008-January/054994.html
> ?

That's exactly it. We tried to submit that code way back then, and Daniel suggested a better route. Unfortunately, we never found the time to work on that since then...
Comment 15 Tom Tromey 2021-08-17 20:08:16 UTC
Daniel's suggestion is basically Tom's patch in comment #4,
so I think we ought to go with that.