[Bug symtab/32299] [gdb/symtab] incorrect parent for cooked index entries

"cvs-commit at gcc dot gnu.org via Gdb-prs" <[email protected]>
Newsgroups gmane.comp.gdb.bugs.discuss
Message-ID <[email protected]/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=32299

--- Comment #3 from Sourceware Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Andrew Burgess <[email protected]>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e18d91f558498184145ae4bb03ce6f56e1e1446b

commit e18d91f558498184145ae4bb03ce6f56e1e1446b
Author: Tom de Vries <[email protected]>
Date:   Thu Oct 24 13:23:25 2024 +0200

    gdb: track parents of nameless DIEs in cooked indexer

    This patch ensures the cooked index correctly resolves parents for
    DIEs whose DW_AT_specification chains pass through unnamed
    intermediate DIEs in a partial unit.

    The test-case is based on the DWARF info generated for test-case
    gdb.cp/breakpoint-locs.exp with target board cc-with-dwz.

    The difference is that the test-case does not contain
    DW_TAG_inlined_subroutine, which makes it possible to submit this patch
    independently from the patch series:

      https://sourceware.org/pipermail/gdb-patches/2023-December/205056.html

    A consequence of this difference is that the relevant DIEs in the
    Partial Unit (PU) are not named, and consequently have no entries in
    the cooked index, which meant that the original fix didn't work, so
    the fix has been updated to handle this case as well.

    Consider the new DWARF assembly test-case
    gdb.dwarf2/dwz-parent-spec-chain.exp.  With readnow, we have:

      $ gdb -q -batch -readnow
outputs/gdb.dwarf2/dwz-parent-spec-chain/dwz-parent-spec-chain \
              -ex "print ns::foo" \
              -ex "print ns::bar"
      $1 = {int (void)} 0x4101ac <ns::foo()>
      $2 = {int (void)} 0x4101b4 <ns::bar()>

    but with the cooked index we have either:

      $1 = {int (void)} 0x4101ac <ns::foo()>
      No symbol "bar" in namespace "ns".

    or:

      No symbol "foo" in namespace "ns".
      $1 = {int (void)} 0x4101b4 <ns::bar()>

    The problem is that both the entries for 'foo' and 'bar' don't have the
correct
    parent:

      $ gdb -q -batch
outputs/gdb.dwarf2/dwz-parent-spec-chain/dwz-parent-spec-chain \
              -ex "maint print objfiles" \
              | egrep "qualified:.*(foo|bar)$"
          qualified:  foo
          qualified:  bar

    so gdb ends up expanding the first CU that contains namespace ns,
    which is the CU that won the import race for the PU, which is why
    we're getting either ns::foo or ns::bar.

    So why are the 'foo' and 'bar' entries not getting the correct parent?

    The DWARF representation of ns::foo and ns::bar is as follows; we have the
foo
    DIE (in CU1):

      <1><42>: Abbrev Number: 3 (DW_TAG_subprogram)
         <43>   DW_AT_specification: <0x2a>
         <47>   DW_AT_name        : foo
         <4b>   DW_AT_low_pc      : 0x4101ac
         <53>   DW_AT_high_pc     : 0x4101b4
         <5b>   DW_AT_linkage_name: _ZN2ns3fooEv

    and the bar DIE (in CU2):

      <1><7b>: Abbrev Number: 3 (DW_TAG_subprogram)
         <7c>   DW_AT_specification: <0x2a>
         <80>   DW_AT_name        : bar
         <84>   DW_AT_low_pc      : 0x4101b4
         <8c>   DW_AT_high_pc     : 0x4101bc
         <94>   DW_AT_linkage_name: _ZN2ns3barEv

    both referring to this DIE (in the PU):

      <1><2a>: Abbrev Number: 5 (DW_TAG_subprogram)
         <2b>   DW_AT_specification: <0x23>

    which refers to this DIE (also in the PU):

      <1><1f>: Abbrev Number: 3 (DW_TAG_namespace)
         <20>   DW_AT_name        : ns
      <2><23>: Abbrev Number: 4 (DW_TAG_subprogram)
         <24>   DW_AT_type        : <0x18>
         <28>   DW_AT_external    : 1

    When processing both the 'foo' and 'bar' DIEs, finding the parent is
deferred, but
    when the deferred parents are resolved there is no entry at 0x2a in the
parent
    map:

      map start:
        0x0000000000000000 0x0
        0x0000000000000020 0x31f497c0 (0x1f: ns)
        0x000000000000002a 0x0

    Fix this by adding an entry at 0x2a in the parent map, such that we have
    instead:

      map start:
        0x0000000000000000 0x0
        0x0000000000000020 0x321117c0 (0x1f: ns)
        0x000000000000002b 0x0
        0x0000000000000042 0x321117c0 (0x1f: ns)
        0x0000000000000043 0x0
        0x000000000000007b 0x321117c0 (0x1f: ns)
        0x000000000000007c 0x0

    and:

      $ gdb -q -batch
outputs/gdb.dwarf2/dwz-parent-spec-chain/dwz-parent-spec-chain \
                -ex "maint print objfiles" \
                | egrep "qualified:.*(foo|bar)$"
          qualified:  ns::foo
          qualified:  ns::bar

    and:

      $ gdb -q -batch
outputs/gdb.dwarf2/dwz-parent-spec-chain/dwz-parent-spec-chain \
              -ex "print ns::foo" \
              -ex "print ns::bar"
      $1 = {int (void)} 0x4101ac <ns::foo()>
      $2 = {int (void)} 0x4101b4 <ns::bar()>

    Tested on aarch64-linux and x86-64-linux.

    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32299

    Approved-By: Tom Tromey <[email protected]>

-- 
You are receiving this mail because:
You are on the CC list for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.