Support anonymous typedef generated by gcc -feliminate-dwarf2-dups

Message ID 20200307022544.GA2485@delia
State New, archived
Headers

Commit Message

Tom de Vries March 7, 2020, 2:25 a.m. UTC
  Hi,

Gcc supports an option -feliminate-dwarf2-dups (up until gcc-7, removed in
gcc-8).

When running tests with target board unix/-feliminate-dwarf2-dups, we run
into:
...
(gdb) PASS: gdb.ada/arraydim.exp: print m'length(3)
ptype global_3dim_for_gdb_testing^M
type = array (Unexpected type in ada_discrete_type_low_bound.^M
(gdb) FAIL: gdb.ada/arraydim.exp: ptype global_3dim_for_gdb_testing
...

The DWARF for the variable global_3dim_for_gdb_testing looks as follows:
...
 <0><824>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <825>   DW_AT_name        : src/gdb/testsuite/gdb.ada/arraydim/inc.c
 <1><832>: Abbrev Number: 2 (DW_TAG_array_type)
    <833>   DW_AT_type        : <0x874>
 <2><837>: Abbrev Number: 3 (DW_TAG_subrange_type)
    <838>   DW_AT_type        : <0x84a>
    <83c>   DW_AT_upper_bound : 0
 <2><83d>: Abbrev Number: 3 (DW_TAG_subrange_type)
    <83e>   DW_AT_type        : <0x84a>
    <842>   DW_AT_upper_bound : 1
 <2><843>: Abbrev Number: 3 (DW_TAG_subrange_type)
    <844>   DW_AT_type        : <0x84a>
    <848>   DW_AT_upper_bound : 2
 <2><849>: Abbrev Number: 0
 <1><84a>: Abbrev Number: 4 (DW_TAG_typedef)
    <84b>   DW_AT_type        : <0x86d>
 <1><84f>: Abbrev Number: 0
 <0><85b>: Abbrev Number: 5 (DW_TAG_compile_unit)
    <861>   DW_AT_name        : src/gdb/testsuite/gdb.ada/arraydim/inc.c
 <1><86d>: Abbrev Number: 6 (DW_TAG_base_type)
    <86e>   DW_AT_byte_size   : 8
    <86f>   DW_AT_encoding    : 7       (unsigned)
    <870>   DW_AT_name        : long unsigned int
 <1><874>: Abbrev Number: 7 (DW_TAG_base_type)
    <875>   DW_AT_byte_size   : 4
    <876>   DW_AT_encoding    : 5       (signed)
    <877>   DW_AT_name        : int
 <1><87b>: Abbrev Number: 8 (DW_TAG_variable)
    <87c>   DW_AT_name        : global_3dim_for_gdb_testing
    <882>   DW_AT_type        : <0x832>
    <886>   DW_AT_external    : 1
...

The DWARF contains an anonymous typedef at 0x84a, referring to 0x86d.
Strictly speaking, the anonymous typedef is illegal DWARF, because a
DW_TAG_typedef is defined to have an DW_AT_name attribute containing the name
of the typedef as it appears in the source program.

The DWARF reading code creates a corresponding type for this typedef, which
goes on to confuse the code handling arrays.

Rather than trying to support the type representing this anonymous typedef in
all the locations where it causes problems, fix this by treating the anonymous
typedef as a forwarder DIE in the DWARF reader.

Tested on x86_64-linux, with target boards unix and
unix/-feliminate-dwarf2-dups.

This fixes ~85 failures for unix/-feliminate-dwarf2-dups.

OK for trunk?

Thanks,
- Tom

[gdb] Support anonymous typedef generated by gcc -feliminate-dwarf2-dups

gdb/ChangeLog:

2020-03-07  Tom de Vries  <tdevries@suse.de>

	* dwarf2/read.c (read_typedef): Treat anonymous typedef as forwarder
	DIE.

---
 gdb/dwarf2/read.c | 5 +++++
 1 file changed, 5 insertions(+)
  

Comments

Simon Marchi March 7, 2020, 4:25 a.m. UTC | #1
On 2020-03-06 9:25 p.m., Tom de Vries wrote:
> Hi,
> 
> Gcc supports an option -feliminate-dwarf2-dups (up until gcc-7, removed in
> gcc-8).
> 
> When running tests with target board unix/-feliminate-dwarf2-dups, we run
> into:
> ...
> (gdb) PASS: gdb.ada/arraydim.exp: print m'length(3)
> ptype global_3dim_for_gdb_testing^M
> type = array (Unexpected type in ada_discrete_type_low_bound.^M
> (gdb) FAIL: gdb.ada/arraydim.exp: ptype global_3dim_for_gdb_testing
> ...
> 
> The DWARF for the variable global_3dim_for_gdb_testing looks as follows:
> ...
>  <0><824>: Abbrev Number: 1 (DW_TAG_compile_unit)
>     <825>   DW_AT_name        : src/gdb/testsuite/gdb.ada/arraydim/inc.c
>  <1><832>: Abbrev Number: 2 (DW_TAG_array_type)
>     <833>   DW_AT_type        : <0x874>
>  <2><837>: Abbrev Number: 3 (DW_TAG_subrange_type)
>     <838>   DW_AT_type        : <0x84a>
>     <83c>   DW_AT_upper_bound : 0
>  <2><83d>: Abbrev Number: 3 (DW_TAG_subrange_type)
>     <83e>   DW_AT_type        : <0x84a>
>     <842>   DW_AT_upper_bound : 1
>  <2><843>: Abbrev Number: 3 (DW_TAG_subrange_type)
>     <844>   DW_AT_type        : <0x84a>
>     <848>   DW_AT_upper_bound : 2
>  <2><849>: Abbrev Number: 0
>  <1><84a>: Abbrev Number: 4 (DW_TAG_typedef)
>     <84b>   DW_AT_type        : <0x86d>
>  <1><84f>: Abbrev Number: 0
>  <0><85b>: Abbrev Number: 5 (DW_TAG_compile_unit)
>     <861>   DW_AT_name        : src/gdb/testsuite/gdb.ada/arraydim/inc.c
>  <1><86d>: Abbrev Number: 6 (DW_TAG_base_type)
>     <86e>   DW_AT_byte_size   : 8
>     <86f>   DW_AT_encoding    : 7       (unsigned)
>     <870>   DW_AT_name        : long unsigned int
>  <1><874>: Abbrev Number: 7 (DW_TAG_base_type)
>     <875>   DW_AT_byte_size   : 4
>     <876>   DW_AT_encoding    : 5       (signed)
>     <877>   DW_AT_name        : int
>  <1><87b>: Abbrev Number: 8 (DW_TAG_variable)
>     <87c>   DW_AT_name        : global_3dim_for_gdb_testing
>     <882>   DW_AT_type        : <0x832>
>     <886>   DW_AT_external    : 1
> ...
> 
> The DWARF contains an anonymous typedef at 0x84a, referring to 0x86d.
> Strictly speaking, the anonymous typedef is illegal DWARF, because a
> DW_TAG_typedef is defined to have an DW_AT_name attribute containing the name
> of the typedef as it appears in the source program.
> 
> The DWARF reading code creates a corresponding type for this typedef, which
> goes on to confuse the code handling arrays.
> 
> Rather than trying to support the type representing this anonymous typedef in
> all the locations where it causes problems, fix this by treating the anonymous
> typedef as a forwarder DIE in the DWARF reader.
> 
> Tested on x86_64-linux, with target boards unix and
> unix/-feliminate-dwarf2-dups.
> 
> This fixes ~85 failures for unix/-feliminate-dwarf2-dups.
> 
> OK for trunk?
> 
> Thanks,
> - Tom
> 
> [gdb] Support anonymous typedef generated by gcc -feliminate-dwarf2-dups
> 
> gdb/ChangeLog:
> 
> 2020-03-07  Tom de Vries  <tdevries@suse.de>
> 
> 	* dwarf2/read.c (read_typedef): Treat anonymous typedef as forwarder
> 	DIE.
> 
> ---
>  gdb/dwarf2/read.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 3556908cf5..bd9fbd698d 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -16816,6 +16816,11 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
>  		 sect_offset_str (die->sect_off), objfile_name (objfile));
>        TYPE_TARGET_TYPE (this_type) = NULL;
>      }
> +  if (name == NULL)
> +    {
> +      set_die_type (die, target_type, cu);
> +      return target_type;
> +    }
>    return this_type;
>  }
>  
> 

Hi Tom,

That's fine with me, but please add a comment that explains:

1. Why would name be ever be NULL here (gcc <= 7 with that option produce invalid DWARF)
2. How we decide to handle it (drop the typedef, just use the type it points to)

The future poor soul who will do refactoring in the DWARF reading code will appreciative it :).

Thanks,

Simon
  

Patch

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 3556908cf5..bd9fbd698d 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -16816,6 +16816,11 @@  read_typedef (struct die_info *die, struct dwarf2_cu *cu)
 		 sect_offset_str (die->sect_off), objfile_name (objfile));
       TYPE_TARGET_TYPE (this_type) = NULL;
     }
+  if (name == NULL)
+    {
+      set_die_type (die, target_type, cu);
+      return target_type;
+    }
   return this_type;
 }