From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id DKIZAQDMhWobuTAAWB0awg (envelope-from ) for ; Wed, 19 Aug 2026 11:30:08 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YzCKNwie; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id DCE941E033; Wed, 19 Aug 2026 11:30:07 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 4A8F31E033 for ; Wed, 19 Aug 2026 11:30:06 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CC17A4BAE7CF for ; Wed, 19 Aug 2026 15:30:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC17A4BAE7CF Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YzCKNwie Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id 6AC114BA9016 for ; Wed, 19 Aug 2026 15:29:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6AC114BA9016 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6AC114BA9016 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787153379; cv=none; b=SD34udhyrA/TyJ+vUm6nEopp0FhuOAAOYFg0EIm6x5V8tYh2BVqofwueezau4dXe9c+hcIkj0sccgCK2HtPRsCfkobzt6ClXBFv6vQXNFIcPmNsLHKKoqgRiKBOsAJPc4RXQ7SoDBVjsBxsv/Upq0jU9Ledr7qX4s6lRWFXjOAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787153379; c=relaxed/simple; bh=Po4j0BZrA6wS9WEPewlMDI2m7itA4hacgrpsmBUadjo=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=wgl4Y/E+aBN6Q/e//5dHANq/7aZk7A6J2C+eZY/lezkL6KokvgGe3sbbR5p0DLx1sLZINNtT4w/WbDkuTyzlUQq8tfD2DbdtADJrm22BcHDYZFdKQ0ixflMy25vkkV0vbbkXyGcpi0nImBYP9bM9tNg6Xv+Z4/uX2++o86xnYOs= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=YzCKNwie DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6AC114BA9016 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1787153379; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BZ1JM+JottM6mgNbS/cvKbwdt/htMOJIIwjGVncQ8SI=; b=YzCKNwie3o3oM2Lsc3nCkhGqHpo8Qpe9sJOEqFj0oDBnX6wd201cSCJgSY8i5jtDJHkWQz hh0J3+xURZxtp3Y9haqCPE+IIQKZVh3VmErUDyEDirPQhzmXEpvLxEhH5y4uIyRy2STAk9 J7UtMfU/0R8C38Qezjhx8xCYHKE6eKQ= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-650-T1qstXTFMYC83IeHVUde2g-1; Wed, 19 Aug 2026 11:29:30 -0400 X-MC-Unique: T1qstXTFMYC83IeHVUde2g-1 X-Mimecast-MFC-AGG-ID: T1qstXTFMYC83IeHVUde2g_1787153369 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-49808ea1b64so9995e9.1 for ; Wed, 19 Aug 2026 08:29:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787153369; x=1787758169; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=BZ1JM+JottM6mgNbS/cvKbwdt/htMOJIIwjGVncQ8SI=; b=T1SQci9hWAeWx5tdyGkiz22NOizd9+YQFGWTuzlpKAjg0v0mMMUyvC6Bw/OTz5geH3 vdy8M74dxPnXqXJAaKvMfHVI+0wuK/ss4iO41jel49AKCWmdXDs1OmrnL67GzpTEZDvA eajhJMtRwIyeLJIDH09/Hpy1Ws7hIYFB/gbZGrkoYzQ+fueOi70d1EfYs2Vs4kU9zIdP DKK1tf1frXAMcl1/GnyhNPhhamGJDZmXWjbkSC6xafhWf2IbX0yZwJ7jPwEMIcFOjJ2v qiFWWDOaVe93eMeF3Yvdi2thuClUkIowH+H9ZRKAoyg6sRH+EfttL/94/Ai84WI+MLcA 4ezA== X-Gm-Message-State: AOJu0YycDXYyf7rvWPnao+7iqzHxB1eGkYbsn+MGmm+9epWdyPLU9g/I uUDGNWYvegoD+R9Fap4D6Fm0AWwS5aXzkbIQn1fKw/ySUis/hhf40afkzU3/kGb7mm0+vLxoXjv FO7N/Sr2QAMB/18pj6uatVo1zenmChEteTzu4TuQTcedRWvxQ4bUt7l4OZU1ylbMMMSoTmriLsW 6OG0SGBXNMFuOC75fuLLI5w3uwkj3eMuUCuzTTABwVT6sSBgY= X-Gm-Gg: AR+sD134fDluXrx3JcM1zl/d8EDlOZnkqvGDjfWLCmM9sJ11wwIUee13lyP4IlVyr10 0mW9D/kW78N8o3dX8HXf2XJoFWuF/PV5v51LJMxHygCISjxjHLIlb+rSFFbOQtWeT1lVfmwt1+K zYqA6/LvWXfXRCwjAJy1hH5IS5ksfocCnfhQKqKBFgnfAL+XPwhi0bZJLJDZFkKkXfNjstoTyxA 5unDJtLj4fTjkqD9hoPjTGYO0gIM3K3ppnM5SRdXl9yYGIHtKI7UnjeTbhl+/pmOweyYtzRJEeA IcEHDigIwwmvbYQSFuZeGDeDYMo+VDSnHeauP5I/GNp5AaFXn+6CRYVHF43xZjesI0ncZdPD/9j MkI338SS7vmAz47dX5ME= X-Received: by 2002:a05:600c:5943:b0:493:e543:1dd9 with SMTP id 5b1f17b1804b1-499aa11e5famr69821225e9.9.1787153369056; Wed, 19 Aug 2026 08:29:29 -0700 (PDT) X-Received: by 2002:a05:600c:5943:b0:493:e543:1dd9 with SMTP id 5b1f17b1804b1-499aa11e5famr69820265e9.9.1787153368240; Wed, 19 Aug 2026 08:29:28 -0700 (PDT) Received: from localhost (67.72.115.87.dyn.plus.net. [87.115.72.67]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-499a9b6d497sm62844825e9.1.2026.08.19.08.29.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Aug 2026 08:29:27 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Tom de Vries Subject: [PATCH] gdb: track parents of nameless DIEs in cooked indexer Date: Wed, 19 Aug 2026 16:29:22 +0100 Message-Id: <4c16f81081452e05f47741be7a2d15a250827c52.1787152777.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: hvOdsz9tGhe2EPTZgWr-V9TgroiOBncBBp_vW3HnjF4_1787153369 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org From: Tom de Vries This patch is being posted by Andrew, but I have left the author attribution as Tom de Vries as the changes I've made here are not significant. The version of this patch I picked up can be found here: https://inbox.sourceware.org/gdb-patches/20241024112325.868-1-tdevries@suse.de I found this patch while looking at PR gdb/33447, Tom Tromey had suggest this patch might fix that bug, so I took the patch from the mailing list, rebased it to current HEAD, checked the test still passed, and then checked to see if it fixed PR gdb/33447. Turns out this doesn't fix that bug, but by that point I'd already done most of the work to update this patch, so it seemed a shame to just discard it. Things I have changed: 1. The code adds additional DIEs to the parent map, but the bug is specifically about nameless DIEs not being tracked. I tweaked the code so that only nameless DIEs are being added to the map (by this patch). The test still passes, so I think this confirms my understanding of what's going on here. This helps keep the map smaller, which is a very minor memory saving, and possibly the lookups are faster too. 2. I renamed the test. I'm not a fan of names like 'dwz-2.exp', what's next? dwz-3.exp, dwz-4.exp, ... I tried to find a name which hinted at what was being tested. 3. I added a comment on the new code to try an explain what's going on. 4. I reworded some parts of the commit message to make things clearer. Any errors introduced by my changes are all my own fault. Thanks, Andrew --- 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 $2 = {int (void)} 0x4101b4 but with the cooked index we have either: $1 = {int (void)} 0x4101ac No symbol "bar" in namespace "ns". or: No symbol "foo" in namespace "ns". $1 = {int (void)} 0x4101b4 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 $2 = {int (void)} 0x4101b4 Tested on aarch64-linux and x86-64-linux. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32299 --- gdb/dwarf2/cooked-indexer.c | 11 ++ .../gdb.dwarf2/dwz-parent-spec-chain.c | 37 ++++++ .../gdb.dwarf2/dwz-parent-spec-chain.exp | 125 ++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.c create mode 100644 gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.exp diff --git a/gdb/dwarf2/cooked-indexer.c b/gdb/dwarf2/cooked-indexer.c index f55efc5e3a0..581c0eb0763 100644 --- a/gdb/dwarf2/cooked-indexer.c +++ b/gdb/dwarf2/cooked-indexer.c @@ -625,6 +625,17 @@ cooked_indexer::index_dies (cutu_reader *reader, m_language, name, this_parent_entry, cu_for_entry); } + else if (this_parent_entry != nullptr) + { + /* Record this DIE's parent in the map so that deferred + parent lookups through DW_AT_specification chains can + find the parent even for DIEs that have no name and thus + no cooked_index_entry. */ + parent_map::addr_type addr + = parent_map::form_addr (reader->buffer () + + to_underlying (this_die)); + m_die_range_map->add_entry (addr, addr, this_parent_entry); + } if (linkage_name != nullptr) { diff --git a/gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.c b/gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.c new file mode 100644 index 00000000000..ffaf1e2b660 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.c @@ -0,0 +1,37 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2024-2026 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 . */ + +int +foo (void) +{ + asm ("foo_label: .globl foo_label"); + return 1; +} + +int +bar (void) +{ + asm ("bar_label: .globl bar_label"); + return 2; +} + +int +main (void) +{ + asm ("main_label: .globl main_label"); + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.exp b/gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.exp new file mode 100644 index 00000000000..6de09fb0b07 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dwz-parent-spec-chain.exp @@ -0,0 +1,125 @@ +# Copyright 2024-2026 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 . + +# 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) +# +# In the above '-s->' is a DW_AT_specification link and '-ao->' is a +# DW_AT_abstract_origin link. + +load_lib dwarf.exp + +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: DW_TAG_partial_unit {} { + int_label: DW_TAG_base_type { + DW_AT_name int + DW_AT_byte_size 4 sdata + DW_AT_encoding @DW_ATE_signed + } + + DW_TAG_namespace { + DW_AT_name ns + } { + decl1: DW_TAG_subprogram { + DW_AT_type :$int_label + DW_AT_external 1 flag + } + } + + decl2: DW_TAG_subprogram { + DW_AT_specification %$decl1 + } + } + } + + cu {} { + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { + DW_TAG_imported_unit { + DW_AT_import $partial_label ref_addr + } + + DW_TAG_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 {} { + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { + DW_TAG_imported_unit { + DW_AT_import $partial_label ref_addr + } + + DW_TAG_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 + } + + DW_TAG_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 +} + +# 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 " "] +gdb_test "p ns::bar" \ + [string_to_regexp " "] base-commit: afa6db16e6508d8ea269557085bc7c301e824382 -- 2.25.4