]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
gdb/dwarf: fix spurious error when encountering dummy CU
authorSimon Marchi <simon.marchi@polymtl.ca>
Mon, 17 Mar 2025 14:34:29 +0000 (10:34 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Tue, 18 Mar 2025 13:39:01 +0000 (09:39 -0400)
commitaab6de1613df693059a6a2b505cc8f20d479d109
tree003759d127b36194650fd4032db6c7f0effb3990
parent71a48752660b0771237ce1d3e9075db24800df60
gdb/dwarf: fix spurious error when encountering dummy CU

I built an application with -gsplit-dwarf (i.e. dwo), and some CUs are
considered "dummy" by the DWARF reader.  That is, the top-level DIE
(DW_TAG_compile_unit) does not have any children.  Here's the skeleton:

    0x0000c0cb: Compile Unit: length = 0x0000001d, format = DWARF32, version = 0x0005, unit_type = DW_UT_skeleton, abbr_offset = 0x529b, addr_size = 0x08, DWO_id = 0x0ed2693dd2a756dc (next unit at 0x0000c0ec)

    0x0000c0df: DW_TAG_skeleton_unit
                  DW_AT_stmt_list [DW_FORM_sec_offset]      (0x09dee00f)
                  DW_AT_dwo_name [DW_FORM_strp]     ("CMakeFiles/lib_crl.dir/crl/dispatch/crl_dispatch_queue.cpp.dwo")
                  DW_AT_comp_dir [DW_FORM_strp]     ("/home/simark/src/tdesktop/build-relwithdebuginfo-split-nogz/Telegram/lib_crl")
                  DW_AT_GNU_pubnames [DW_FORM_flag_present] (true)

And here's the entire debug info in the .dwo file:

    .debug_info.dwo contents:
    0x00000000: Compile Unit: length = 0x0000001a, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = 0x0ed2693dd2a756dc (next unit at 0x0000001e)

    0x00000014: DW_TAG_compile_unit
                  DW_AT_producer [DW_FORM_strx]     ("GNU C++20 14.2.1 20250207 -mno-direct-extern-access -mtune=generic -march=x86-64 -gsplit-dwarf -g3 -gz=none -O2 -std=gnu++20 -fPIC -fno-strict-aliasing")
                  DW_AT_language [DW_FORM_data1]    (DW_LANG_C_plus_plus_14)
                  DW_AT_name [DW_FORM_strx] ("/home/simark/src/tdesktop/Telegram/lib_crl/crl/dispatch/crl_dispatch_queue.cpp")
                  DW_AT_comp_dir [DW_FORM_strx]     ("/home/simark/src/tdesktop/build-relwithdebuginfo-split-nogz/Telegram/lib_crl")

When loading the binary in GDB, I see some warnings:

    $ ./gdb -q -nx --data-directory=data-directory -ex 'maint set dwarf sync on' -ex  "file /home/simark/src/tdesktop/build-relwithdebuginfo-split-nogz/telegram-desktop"
    Reading symbols from /home/simark/src/tdesktop/build-relwithdebuginfo-split-nogz/telegram-desktop...
    DWARF Error: unexpected tag 'DW_TAG_skeleton_unit' at offset 0xc0cb
    DWARF Error: unexpected tag 'DW_TAG_skeleton_unit' at offset 0xc152
    DWARF Error: unexpected tag 'DW_TAG_skeleton_unit' at offset 0xc194
    DWARF Error: unexpected tag 'DW_TAG_skeleton_unit' at offset 0xc1b5
    (gdb)

It turns out that these errors are not really justified.  What happens
is:

 - cutu_reader::read_cutu_die_from_dwo return 0, indicating that the CU
   is "dummy"
 - back in cutu_reader::cutu_reader, we omit setting m_top_level_die to
   the DIE from the dwo file, meaning that m_top_level_die keeps
   pointing to the DIE from the main file (DW_TAG_skeleton_unit)
 - later, in cutu_reader::prepare_one_comp_unit, there is a check that
   m_top_level_die->tag is one of DW_TAG_{compile,partial,type}_unit,
   which triggers

My proposal to fix this is to set m_top_level_die even if the CU is
dummy.  Even if the top-level DIE does not have any children, I don't
see any reason to leave cutu_reader::m_top_level_die in a different
state than when the CU is not dummy.

While at it, set m_dummy_p directly in read_cutu_die_from_dwo, instead
of returning a value and having the caller do it.  This is all inside
cutu_reader anyway.

Change-Id: I483a68a369bb461a8dfa5bf2106ab1d6a0067198
Approved-By: Tom Tromey <tom@tromey.com>
gdb/dwarf2/read.c
gdb/dwarf2/read.h