From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Subject: [PING][PATCH] [gdb/symtab] Keep track of all parents for cooked index
Date: Fri, 15 Nov 2024 15:34:21 +0100 [thread overview]
Message-ID: <bbb38420-c896-43fa-9c0d-681801d392b8@suse.de> (raw)
In-Reply-To: <20241024112325.868-1-tdevries@suse.de>
On 10/24/24 13:23, Tom de Vries wrote:
> [ This is a resubmission of v2 of "[gdb/symtab] Keep track of all parents for
> cooked index" [1], this time with a DWARF assembly test-case.
>
> 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.
>
> A consequence of this difference is that the relevant DIEs in the 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-2.exp.
>
> With readnow, we have:
> ...
> $ gdb -q -batch -readnow outputs/gdb.dwarf2/dwz-2/dwz-2 \
> -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-2/dwz-2 -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-2/dwz-2 -ex "maint print objfiles" \
> | egrep "qualified:.*(foo|bar)$"
> qualified: ns::foo
> qualified: ns::bar
> ...
> and:
> ...
> $ gdb -q -batch outputs/gdb.dwarf2/dwz-2/dwz-2 \
> -ex "print ns::foo" \
> -ex "print ns::bar"
> $1 = {int (void)} 0x4101ac <ns::foo()>
> $2 = {int (void)} 0x4101b4 <ns::bar()>
> ...
>
> Tested on aarch64-linux.
>
Ping.
Thanks,
- Tom
> PR symtab/32299
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32299
>
> [1] https://sourceware.org/pipermail/gdb-patches/2023-December/205056.html
> ---
> gdb/dwarf2/read.c | 8 ++
> gdb/testsuite/gdb.dwarf2/dwz-2.c | 37 +++++++++
> gdb/testsuite/gdb.dwarf2/dwz-2.exp | 116 +++++++++++++++++++++++++++++
> 3 files changed, 161 insertions(+)
> create mode 100644 gdb/testsuite/gdb.dwarf2/dwz-2.c
> create mode 100644 gdb/testsuite/gdb.dwarf2/dwz-2.exp
>
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 6ac6f7c6a39..cacfab7e6d5 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -16601,6 +16601,14 @@ cooked_indexer::index_dies (cutu_reader *reader,
> this_parent_entry, m_per_cu);
> }
>
> + if (this_parent_entry != nullptr)
> + {
> + parent_map::addr_type addr
> + = parent_map::form_addr (this_die,
> + reader->cu->per_cu->is_dwz);
> + m_die_range_map->add_entry (addr, addr, this_parent_entry);
> + }
> +
> if (linkage_name != nullptr)
> {
> /* We only want this to be "main" if it has a linkage name
> diff --git a/gdb/testsuite/gdb.dwarf2/dwz-2.c b/gdb/testsuite/gdb.dwarf2/dwz-2.c
> new file mode 100644
> index 00000000000..7b3236e980a
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/dwz-2.c
> @@ -0,0 +1,37 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2024 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +int
> +foo (void)
> +{
> + asm ("foo_label: .globl foo_label");
> + return 1;
> +}
> +
> +int
> +bar (void)
> +{
> + asm ("bar_label: .globl bar_label");
> + return 2;
> +}
> +
> +int
> +main()
> +{
> + asm ("main_label: .globl main_label");
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.dwarf2/dwz-2.exp b/gdb/testsuite/gdb.dwarf2/dwz-2.exp
> new file mode 100644
> index 00000000000..17508926340
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/dwz-2.exp
> @@ -0,0 +1,116 @@
> +# Copyright 2024 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# Check that the cooked index gets the correct parents for some entries with
> +# the parents in a partial unit.
> +#
> +# The structure is similar to what's generated for test-case
> +# gdb.cp/breakpoint-locs.exp with gcc and target board cc-with-dwz, only in
> +# that case we have:
> +# DW_TAG_inlined_subroutine -ao-> decl DW_TAG_subprogram -s->
> +# (DW_TAG_namespace::DW_TAG_class_type::decl DW_TAG_subprogram)
> +# and here we use:
> +# DW_TAG_subprogram -s-> decl DW_TAG_subprogram -s->
> +# (DW_TAG_namespace::decl DW_TAG_subprogram)
> +
> +load_lib dwarf.exp
> +
> +# This test can only be run on targets which support DWARF-2 and use gas.
> +require dwarf2_support
> +
> +standard_testfile .c dwz.S
> +
> +# Create the DWARF.
> +set asm_file [standard_output_file $srcfile2]
> +Dwarf::assemble $asm_file {
> + get_func_info foo
> + get_func_info bar
> + get_func_info main
> +
> + declare_labels partial_label int_label decl1 decl2
> +
> + cu {} {
> + partial_label: partial_unit {} {
> + int_label: base_type {
> + {name int}
> + {byte_size 4 sdata}
> + {encoding @DW_ATE_signed}
> + }
> +
> + DW_TAG_namespace {
> + {DW_AT_name ns}
> + } {
> + decl1: subprogram {
> + {type :$int_label}
> + {external 1 flag}
> + }
> + }
> +
> + decl2: subprogram {
> + {DW_AT_specification %$decl1}
> + }
> + }
> + }
> +
> + cu {} {
> + compile_unit {{language @DW_LANG_C_plus_plus}} {
> + imported_unit {
> + {import $partial_label ref_addr}
> + }
> +
> + subprogram {
> + {DW_AT_specification %$decl2}
> + {DW_AT_name foo}
> + {DW_AT_low_pc $foo_start DW_FORM_addr}
> + {DW_AT_high_pc $foo_end DW_FORM_addr}
> + {DW_AT_linkage_name _ZN2ns3fooEv}
> + }
> + }
> + }
> +
> + cu {} {
> + compile_unit {{language @DW_LANG_C_plus_plus}} {
> + imported_unit {
> + {import $partial_label ref_addr}
> + }
> +
> + subprogram {
> + {DW_AT_specification %$decl2}
> + {DW_AT_name bar}
> + {DW_AT_low_pc $bar_start DW_FORM_addr}
> + {DW_AT_high_pc $bar_end DW_FORM_addr}
> + {DW_AT_linkage_name _ZN2ns3barEv}
> + }
> +
> + subprogram {
> + {DW_AT_name main}
> + {DW_AT_low_pc $main_start DW_FORM_addr}
> + {DW_AT_high_pc $main_end DW_FORM_addr}
> + }
> + }
> + }
> +}
> +
> +if { [prepare_for_testing "failed to prepare" $testfile \
> + [list $asm_file $srcfile] {nodebug}] } {
> + return -1
> +}
> +
> +# Regression test for PR32299. These should both pass, but before the fix
> +# only one of them passed.
> +gdb_test "p ns::foo" \
> + [string_to_regexp " <ns::foo()>"]
> +gdb_test "p ns::bar" \
> + [string_to_regexp " <ns::bar()>"]
>
> base-commit: 86b26b453f65404b29ce035a2eb3d62671aa0612
next prev parent reply other threads:[~2024-11-15 14:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-24 11:23 [PATCH] " Tom de Vries
2024-11-15 14:34 ` Tom de Vries [this message]
2026-08-19 15:30 ` Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bbb38420-c896-43fa-9c0d-681801d392b8@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox