[2/2] gdb/dwarf: skip type units in create_dwo_cus_hash_table

Message ID 20250411203844.99714-2-simon.marchi@efficios.com
State New
Headers
Series [1/2] gdb/dwarf: rename some functions to specify "dwo" |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed

Commit Message

Simon Marchi April 11, 2025, 8:38 p.m. UTC
  When compiling with -gsplit-dwarf -fdebug-types-section, DWARF 5
.debug_info.dwo sections may contain some type units:

    $ llvm-dwarfdump -F -color a-test.dwo | head -n 5
    a-test.dwo:     file format elf64-x86-64

    .debug_info.dwo contents:
    0x00000000: Type Unit: length = 0x000008a0, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = 'vector<int, std::allocator<int> >', type_signature = 0xb499dcf29e2928c4, type_offset = 0x0023 (next unit at 0x000008a4)

In this case, create_dwo_cus_hash_table wrongly creates a dwo_unit for
it and adds it to dwo_file::cus.  create_dwo_debug_type_hash_table later
correctly creates a dwo_unit that it puts in dwo_file::tus.

This can be observed with:

    $ ./gdb  -nx -q --data-directory=data-directory -ex 'maint set dwarf sync on' -ex "maint set worker-threads 0" -ex "set debug dwarf-read 2" -ex "file a.out" -batch
    ...
    [dwarf-read] create_dwo_cus_hash_table: Reading .debug_info.dwo for /home/smarchi/build/binutils-gdb/gdb/a-test.dwo:
    [dwarf-read] create_dwo_cus_hash_table:   offset 0x0, dwo_id 0xb499dcf29e2928c4
    [dwarf-read] create_dwo_cus_hash_table:   offset 0x8a4, dwo_id 0x496a8791a842701b
    [dwarf-read] create_dwo_cus_hash_table:   offset 0x941, dwo_id 0xefd13b3f62ea9fea
    ...
    [dwarf-read] create_dwo_debug_type_hash_table: Reading .debug_info.dwo for /home/smarchi/build/binutils-gdb/gdb/a-test.dwo
    [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x0, signature 0xb499dcf29e2928c4
    [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x8a4, signature 0x496a8791a842701b
    [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x941, signature 0xefd13b3f62ea9fea
    ...

Fix it by skipping anything that isn't a compile unit in
create_dwo_cus_hash_table.  After this patch, the debug output of
create_dwo_cus_hash_table only shows one created dwo_unit, as we expect.

I couldn't find any user-visible problem related to this, I just noticed
it while debugging.

Change-Id: I7dddf766fe1164123b6702027b1beb56114f25b1
---
 gdb/dwarf2/read.c | 6 ++++++
 1 file changed, 6 insertions(+)
  

Comments

Tom de Vries April 14, 2025, 7:38 p.m. UTC | #1
On 4/11/25 22:38, Simon Marchi wrote:
> When compiling with -gsplit-dwarf -fdebug-types-section, DWARF 5
> .debug_info.dwo sections may contain some type units:
> 
>      $ llvm-dwarfdump -F -color a-test.dwo | head -n 5
>      a-test.dwo:     file format elf64-x86-64
> 
>      .debug_info.dwo contents:
>      0x00000000: Type Unit: length = 0x000008a0, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = 'vector<int, std::allocator<int> >', type_signature = 0xb499dcf29e2928c4, type_offset = 0x0023 (next unit at 0x000008a4)
> 
> In this case, create_dwo_cus_hash_table wrongly creates a dwo_unit for
> it and adds it to dwo_file::cus.  create_dwo_debug_type_hash_table later
> correctly creates a dwo_unit that it puts in dwo_file::tus.
> 
> This can be observed with:
> 
>      $ ./gdb  -nx -q --data-directory=data-directory -ex 'maint set dwarf sync on' -ex "maint set worker-threads 0" -ex "set debug dwarf-read 2" -ex "file a.out" -batch
>      ...
>      [dwarf-read] create_dwo_cus_hash_table: Reading .debug_info.dwo for /home/smarchi/build/binutils-gdb/gdb/a-test.dwo:
>      [dwarf-read] create_dwo_cus_hash_table:   offset 0x0, dwo_id 0xb499dcf29e2928c4
>      [dwarf-read] create_dwo_cus_hash_table:   offset 0x8a4, dwo_id 0x496a8791a842701b
>      [dwarf-read] create_dwo_cus_hash_table:   offset 0x941, dwo_id 0xefd13b3f62ea9fea
>      ...
>      [dwarf-read] create_dwo_debug_type_hash_table: Reading .debug_info.dwo for /home/smarchi/build/binutils-gdb/gdb/a-test.dwo
>      [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x0, signature 0xb499dcf29e2928c4
>      [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x8a4, signature 0x496a8791a842701b
>      [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x941, signature 0xefd13b3f62ea9fea
>      ...
> 
> Fix it by skipping anything that isn't a compile unit in
> create_dwo_cus_hash_table.  After this patch, the debug output of
> create_dwo_cus_hash_table only shows one created dwo_unit, as we expect.
> 
> I couldn't find any user-visible problem related to this, I just noticed
> it while debugging.
> 

LGTM.

Just this nit:
...
$ git show --check
   ...
gdb/dwarf2/read.c:6346: indent with spaces.
+         everything that is not a compile unit.  */
...

Reviewed-By: Tom de Vries <tdevries@suse.de>

Thanks,
- Tom

> Change-Id: I7dddf766fe1164123b6702027b1beb56114f25b1
> ---
>   gdb/dwarf2/read.c | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 7d6dfd03e272..4ffb6ea5eddb 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -6342,6 +6342,12 @@ create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
>         if (reader.is_dummy())
>   	continue;
>   
> +      /* DWARF 5 .debug_info.dwo sections may contain some type units.  Skip
> +         everything that is not a compile unit.  */
> +      if (const auto ut = reader.cu ()->header.unit_type;
> +	  ut != DW_UT_compile && ut != DW_UT_split_compile)
> +	continue;
> +
>         std::optional<ULONGEST> signature
>   	= lookup_dwo_id (reader.cu (), reader.top_level_die ());
>         if (!signature.has_value ())
  
Simon Marchi April 15, 2025, 2:56 p.m. UTC | #2
On 4/14/25 3:38 PM, Tom de Vries wrote:
> On 4/11/25 22:38, Simon Marchi wrote:
>> When compiling with -gsplit-dwarf -fdebug-types-section, DWARF 5
>> .debug_info.dwo sections may contain some type units:
>>
>>      $ llvm-dwarfdump -F -color a-test.dwo | head -n 5
>>      a-test.dwo:     file format elf64-x86-64
>>
>>      .debug_info.dwo contents:
>>      0x00000000: Type Unit: length = 0x000008a0, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_type, abbr_offset = 0x0000, addr_size = 0x08, name = 'vector<int, std::allocator<int> >', type_signature = 0xb499dcf29e2928c4, type_offset = 0x0023 (next unit at 0x000008a4)
>>
>> In this case, create_dwo_cus_hash_table wrongly creates a dwo_unit for
>> it and adds it to dwo_file::cus.  create_dwo_debug_type_hash_table later
>> correctly creates a dwo_unit that it puts in dwo_file::tus.
>>
>> This can be observed with:
>>
>>      $ ./gdb  -nx -q --data-directory=data-directory -ex 'maint set dwarf sync on' -ex "maint set worker-threads 0" -ex "set debug dwarf-read 2" -ex "file a.out" -batch
>>      ...
>>      [dwarf-read] create_dwo_cus_hash_table: Reading .debug_info.dwo for /home/smarchi/build/binutils-gdb/gdb/a-test.dwo:
>>      [dwarf-read] create_dwo_cus_hash_table:   offset 0x0, dwo_id 0xb499dcf29e2928c4
>>      [dwarf-read] create_dwo_cus_hash_table:   offset 0x8a4, dwo_id 0x496a8791a842701b
>>      [dwarf-read] create_dwo_cus_hash_table:   offset 0x941, dwo_id 0xefd13b3f62ea9fea
>>      ...
>>      [dwarf-read] create_dwo_debug_type_hash_table: Reading .debug_info.dwo for /home/smarchi/build/binutils-gdb/gdb/a-test.dwo
>>      [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x0, signature 0xb499dcf29e2928c4
>>      [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x8a4, signature 0x496a8791a842701b
>>      [dwarf-read] create_dwo_debug_type_hash_table:   offset 0x941, signature 0xefd13b3f62ea9fea
>>      ...
>>
>> Fix it by skipping anything that isn't a compile unit in
>> create_dwo_cus_hash_table.  After this patch, the debug output of
>> create_dwo_cus_hash_table only shows one created dwo_unit, as we expect.
>>
>> I couldn't find any user-visible problem related to this, I just noticed
>> it while debugging.
>>
> 
> LGTM.
> 
> Just this nit:
> ...
> $ git show --check
>   ...
> gdb/dwarf2/read.c:6346: indent with spaces.
> +         everything that is not a compile unit.  */
> ...
> 
> Reviewed-By: Tom de Vries <tdevries@suse.de>

Thanks, pushed both patches with fixes.

Simon
  

Patch

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 7d6dfd03e272..4ffb6ea5eddb 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -6342,6 +6342,12 @@  create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
       if (reader.is_dummy())
 	continue;
 
+      /* DWARF 5 .debug_info.dwo sections may contain some type units.  Skip
+         everything that is not a compile unit.  */
+      if (const auto ut = reader.cu ()->header.unit_type;
+	  ut != DW_UT_compile && ut != DW_UT_split_compile)
+	continue;
+
       std::optional<ULONGEST> signature
 	= lookup_dwo_id (reader.cu (), reader.top_level_die ());
       if (!signature.has_value ())