On openSUSE Leap 15.6 x86_64, I see regressions with current trunk for c++ testcases: - gdb.base/condbreak-multi-context.exp - gdb.cp/m-static.exp - gdb.cp/namespace.exp First failure: ... (gdb) print aaa^M $3 = <optimized out>^M (gdb) FAIL: gdb.base/condbreak-multi-context.exp: start_before=true: scenario_1: print aaa ... Variable A::aaa is a static const int: ... class A : public Base { public: static const int aaa = 10; void func () {} }; ... with dwarf: ... <2><350>: Abbrev Number: 3 (DW_TAG_member) <351> DW_AT_name : aaa <35b> DW_AT_external : 1 <35b> DW_AT_accessibility: 1 (public) <35c> DW_AT_declaration : 1 <35c> DW_AT_const_value : 4 byte block: a 0 0 0 ... Minimal example: ... $ gdb -q -batch \ outputs/gdb.base/condbreak-multi-context/condbreak-multi-context \ -ex "p A::aaa" $1 = <optimized out> ... With system gdb (14.2): ... $ gdb -q -batch \ outputs/gdb.base/condbreak-multi-context/condbreak-multi-context \ -ex "p A::aaa" $1 = 10 ...
(In reply to Tom de Vries from comment #0) > First failure: > ... > (gdb) print aaa^M > $3 = <optimized out>^M > (gdb) FAIL: gdb.base/condbreak-multi-context.exp: start_before=true: > scenario_1: print aaa > ... Bisects to: ... commit 86ac8c546235a67d6a6bb29476a3a9ac8f7a620a Date: Thu Jan 2 15:28:18 2025 -0700 Convert lookup_symbol_in_objfile ...
No regression on Tumbleweed with gcc 15.2. There we have: ... <2><356>: Abbrev Number: 2 (DW_TAG_variable) <357> DW_AT_name : aaa <35c> DW_AT_linkage_name: (indirect string, offset: 0x4ae): _ZN1A3aaaE <364> DW_AT_external : 1 <364> DW_AT_accessibility: 1 (public) <364> DW_AT_declaration : 1 <364> DW_AT_const_value : 10 ... and there are entries in the cooked index representing aaa: ... [45] ((cooked_index_entry *) 0x7facf0004730) name: _ZN1A3aaaE canonical: _ZN1A3aaaE qualified: _ZN1A3aaaE DWARF tag: DW_TAG_variable flags: 0x4 [IS_LINKAGE] DIE offset: 0x356 parent: ((cooked_index_entry *) 0) [52] ((cooked_index_entry *) 0x7facf0004700) name: aaa canonical: aaa qualified: A::aaa DWARF tag: DW_TAG_variable flags: 0x0 [] DIE offset: 0x356 parent: ((cooked_index_entry *) 0x7facf00046d0) [A] ... So, maybe the problem is that the DW_TAG_member doesn't result in a cooked index entry. Indeed, it's not listed in tag_interesting_for_index.
Created attachment 16334 [details] Tentative patch
https://sourceware.org/pipermail/gdb-patches/2025-September/220814.html
FWIW this is a compiler bug. A C++ class variable should be emitted using DW_TAG_variable. If we want to work around this bug, the workaround should probably be a bit more targeted. Like, only DW_TAG_member with a DW_AT_const_value -- though I'm not sure if that is sufficient, what does that compiler emit for an ordinary class variable (one with a separate definition)?
(In reply to Tom Tromey from comment #5) > FWIW this is a compiler bug. > A C++ class variable should be emitted using DW_TAG_variable. > > If we want to work around this bug, the workaround should > probably be a bit more targeted. Like, only DW_TAG_member > with a DW_AT_const_value -- though I'm not sure if that is > sufficient, what does that compiler emit for an ordinary > class variable (one with a separate definition)? [ AFAIU, the affected compilers are gcc 7 - 15, with -gdwarf-4. ] For: ... class A { public: static int aaa; }; int A::aaa = 10; int main (void) { return A::aaa; } ... I get: ... <1><316>: Abbrev Number: 5 (DW_TAG_variable) <317> DW_AT_specification: <0x302> <31b> DW_AT_decl_line : 7 <31c> DW_AT_linkage_name: (indirect string, offset: 0x4d7): _ZN1A3aaaE <320> DW_AT_location : 9 byte block: 3 10 20 40 0 0 0 0 0 (DW_OP_addr: 402010) ... and: ... <2><302>: Abbrev Number: 3 (DW_TAG_member) <303> DW_AT_name : aaa <307> DW_AT_decl_file : 1 <308> DW_AT_decl_line : 4 <309> DW_AT_type : <0x30f> <30d> DW_AT_external : 1 <30d> DW_AT_accessibility: 1 (public) <30e> DW_AT_declaration : 1 ... and that works fine without the fix proposed in this PR. So I think the more targeted approach could work. This works for me: ... diff --git a/gdb/dwarf2/abbrev.c b/gdb/dwarf2/abbrev.c index ec173bb00ee..74cb44698ec 100644 --- a/gdb/dwarf2/abbrev.c +++ b/gdb/dwarf2/abbrev.c @@ -120,6 +120,7 @@ abbrev_table::read (struct dwarf2_section_info *section, bool has_name = false; bool has_linkage_name = false; bool has_external = false; + bool has_const_value = false; /* Now read in declarations. */ int num_attrs = 0; @@ -177,6 +178,10 @@ abbrev_table::read (struct dwarf2_section_info *section, if (is_csize && cur_attr.form == DW_FORM_ref4) sibling_offset = size; break; + + case DW_AT_const_value: + has_const_value = true; + break; } switch (cur_attr.form) @@ -245,7 +250,7 @@ abbrev_table::read (struct dwarf2_section_info *section, } else if (has_hardcoded_declaration && ((cur_abbrev->tag != DW_TAG_variable - && cur_abbrev->tag != DW_TAG_member) + && (cur_abbrev->tag != DW_TAG_member || !has_const_value)) || !has_external)) { cur_abbrev->interesting = false; ...
*** Bug 33557 has been marked as a duplicate of this bug. ***
Setting target milestone to 18.1, as in PR33557.
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d03293898d81e4273ac7f9163a8186dba46db0e5 commit d03293898d81e4273ac7f9163a8186dba46db0e5 Author: Tom de Vries <tdevries@suse.de> Date: Wed Dec 3 09:07:30 2025 +0100 [gdb/symtab] Fix DW_TAG_member regression On openSUSE Leap 15.6 x86_64, with gcc 7 and test-case gdb.base/condbreak-multi-context.exp I run into: ... (gdb) print aaa^M $3 = <optimized out>^M (gdb) FAIL: $exp: start_before=true: scenario_1: print aaa ... This is a regression since commit 86ac8c54623 ("Convert lookup_symbol_in_objfile"). Likewise in test-cases gdb.cp/m-static.exp and gdb.cp/namespace.exp. The failure is specific to using Dwarf v4: - using target board unix/gdb:debug_flags=-gdwarf-5 fixes it - using target board unix/gdb:debug_flags=-gdwarf-4 on Tumbleweed (with gcc 15 and Dwarf v5 default) triggers it The variable we're trying to print, A::aaa is a static const int member: ... class A : public Base { public: static const int aaa = 10; ... }; ... With Dwarf v5, we have this DIE: ... <2><356>: Abbrev Number: 2 (DW_TAG_variable) <357> DW_AT_name : aaa <35c> DW_AT_linkage_name: _ZN1A3aaaE <364> DW_AT_external : 1 <364> DW_AT_accessibility: 1 (public) <364> DW_AT_declaration : 1 <364> DW_AT_const_value : 10 ... and the cooked index contains these corresponding entries: ... [45] ((cooked_index_entry *) 0x7facf0004730) name: _ZN1A3aaaE canonical: _ZN1A3aaaE qualified: _ZN1A3aaaE DWARF tag: DW_TAG_variable flags: 0x4 [IS_LINKAGE] DIE offset: 0x356 parent: ((cooked_index_entry *) 0) [52] ((cooked_index_entry *) 0x7facf0004700) name: aaa canonical: aaa qualified: A::aaa DWARF tag: DW_TAG_variable flags: 0x0 [] DIE offset: 0x356 parent: ((cooked_index_entry *) 0x7facf00046d0) [A] ... With Dwarf v4, we have instead the following DIE: ... <2><350>: Abbrev Number: 3 (DW_TAG_member) <351> DW_AT_name : aaa <35b> DW_AT_external : 1 <35b> DW_AT_accessibility: 1 (public) <35c> DW_AT_declaration : 1 <35c> DW_AT_const_value : 4 byte block: a 0 0 0 ... and there are no corresponding entries. Fix this by adding an entry: ... [47] ((cooked_index_entry *) 0x7f5a24004660) name: aaa canonical: aaa qualified: A::aaa DWARF tag: DW_TAG_member flags: 0x0 [] DIE offset: 0x350 parent: ((cooked_index_entry *) 0x7f5a24004630) [A] ... Add a regression test in the form of a dwarf assembly test-case printing the value of variable A::aaa. In the test-case, for A::aaa, DW_FORM_flag is used to encode DW_AT_declaration. In v1 of this patch that mattered (because of using has_hardcoded_declaration in abbrev_table::read), but that's no longer the case. Nevertheless, also add an A::bbb using FORM_flag_present for DW_AT_declaration (and while we're at it, DW_AT_external as well). Also add two variants, for which <optimized out> is printed: - A::ccc: a variant with DW_AT_location instead of DW_AT_const_value, and - A::ddd: a variant without external. This behavior is not part of the regression. I've reproduced it using a system gdb based on 14.2. It's also not specific to using the cooked index, it reproduces with -readnow as well. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com> PR symtab/33415 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33415
Fixed.