[binutils-gdb/gdb-15-branch] [gdb/testsuite] Add gdb.dwarf2/enum-type-c++.exp, regression test for PR31900.

Tom de Vries vries@sourceware.org
Sun Sep 15 13:31:08 GMT 2024


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

commit cac6b1f3b0346f4ed64d018576051e889ace142c
Author: Tom de Vries <tdevries@suse.de>
Date:   Sun Sep 15 15:30:53 2024 +0200

    [gdb/testsuite] Add gdb.dwarf2/enum-type-c++.exp, regression test for PR31900.
    
    Consider the following test-case:
    ...
    $ cat a.h
    namespace ns {
    
    class A {
    public:
      enum {
        val1 = 1
      };
    };
    
    }
    $ cat main.c
    
    ns::A a;
    
    int
    main (void)
    {
      return 0;
    }
    $ cat val1.c
    
    int u1 = ns::A::val1;
    ...
    compiled with debug info:
    ...
    $ g++ main.c val1.c -g
    ...
    
    When trying to print ns::A::val with current trunk and gdb 15.1 we get:
    ...
    $ gdb -q -batch a.out -ex "print ns::A::val1"
    There is no field named val1
    ...
    
    This PR c++/31900.
    
    With gdb 14.2 we get the expected:
    ...
    $ gdb -q -batch a.out -ex "print ns::A::val1"
    $1 = ns::A::val1
    ...
    
    This is a regression since commit 4e417d7bb1c ("Change handling of
    DW_TAG_enumeration_type in DWARF scanner").
    
    Reverting the commit on current trunk fixes the problem.
    
    So how does this problem happen?
    
    First, let's consider the current trunk, with the commit reverted.
    
    Gdb looks for the entry ns::A::val1, and find this entry:
    ...
        [29] ((cooked_index_entry *) 0x7f7830002ef0)
        name:       val1
        canonical:  val1
        qualified:  ns::A::val1
        DWARF tag:  DW_TAG_enumerator
        flags:      0x0 []
        DIE offset: 0x15a
        parent:     ((cooked_index_entry *) 0x7f7830002ec0) [A]
    ...
    and expands the corresponding CU val1.c containing this debug info:
    ...
     <2><14a>: Abbrev Number: 3 (DW_TAG_class_type)
        <14b>   DW_AT_name        : A
        <14d>   DW_AT_byte_size   : 1
     <3><150>: Abbrev Number: 4 (DW_TAG_enumeration_type)
        <151>   DW_AT_encoding    : 7       (unsigned)
        <152>   DW_AT_byte_size   : 4
        <153>   DW_AT_type        : <0x163>
        <159>   DW_AT_accessibility: 1      (public)
     <4><15a>: Abbrev Number: 5 (DW_TAG_enumerator)
        <15b>   DW_AT_name        : val1
        <15f>   DW_AT_const_value : 1
     <4><160>: Abbrev Number: 0
     <3><161>: Abbrev Number: 0
     <2><162>: Abbrev Number: 0
    ...
    after which it finds ns::A::val1 in the expanded symtabs.
    
    Now let's consider the current trunk as is (so, with the commit present).
    
    Gdb looks for the entry ns::A::val1, but doesn't find it because the val1
    entry is missing its parent:
    ...
       [29] ((cooked_index_entry *) 0x7f5240002ef0)
        name:       val1
        canonical:  val1
        qualified:  val1
        DWARF tag:  DW_TAG_enumerator
        flags:      0x0 []
        DIE offset: 0x15a
        parent:     ((cooked_index_entry *) 0)
    ...
    
    Then gdb looks for the entry ns::A, and finds this entry:
    ...
       [3] ((cooked_index_entry *) 0x7f5248002ec0)
        name:       A
        canonical:  A
        qualified:  ns::A
        DWARF tag:  DW_TAG_class_type
        flags:      0x0 []
        DIE offset: 0xdd
        parent:     ((cooked_index_entry *) 0x7f5248002e90) [ns]
    ...
    which corresponds to this debug info, which doesn't contain val1
    due to -fno-eliminate-unused-debug-types:
    ...
     <2><dd>: Abbrev Number: 3 (DW_TAG_class_type)
        <de>   DW_AT_name        : A
        <e0>   DW_AT_byte_size   : 1
     <2><e3>: Abbrev Number: 0
    ...
    
    Gdb expands the corresponding CU main.c, after which it doesn't find
    ns::A::val1 in the expanded symtabs.
    
    The root cause of the problem is the missing parent on the val1
    cooked_index_entry, but this only becomes user-visible through the
    elaborate scenario above.
    
    Add a test-case gdb.dwarf2/enum-type-c++.exp that contains a regression test
    for this problem that doesn't rely on expansion state or
    -feliminate-unused-debug-types, but simply tests for the root cause by
    grepping for ns::A::val1 in the output of "maint print objfile".
    
    Tested on x86_64-linux.
    
    Approved-By: Tom Tromey <tom@tromey.com>
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31900
    (cherry picked from commit 2693187cc58db107db4255756aa5dbbe090f3b6e)

Diff:
---
 gdb/testsuite/gdb.dwarf2/enum-type-c++.cc  | 29 ++++++++++++++++++++
 gdb/testsuite/gdb.dwarf2/enum-type-c++.exp | 44 ++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/gdb/testsuite/gdb.dwarf2/enum-type-c++.cc b/gdb/testsuite/gdb.dwarf2/enum-type-c++.cc
new file mode 100644
index 00000000000..c0ffaad0316
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/enum-type-c++.cc
@@ -0,0 +1,29 @@
+/* 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/>.  */
+
+namespace ns {
+
+class A {
+public:
+  enum {
+    val1 = 1
+  };
+};
+
+}
+
+int u1 = ns::A::val1;
diff --git a/gdb/testsuite/gdb.dwarf2/enum-type-c++.exp b/gdb/testsuite/gdb.dwarf2/enum-type-c++.exp
new file mode 100644
index 00000000000..44ad225de02
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/enum-type-c++.exp
@@ -0,0 +1,44 @@
+# 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/>.
+
+require !readnow
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+require dwarf2_support
+
+standard_testfile main.c .cc
+
+if { [prepare_for_testing "failed to prepare" $testfile \
+	  [list $srcfile $srcfile2] {debug c++}] } {
+    return -1
+}
+
+require {string equal [have_index $binfile] ""}
+
+set re_ws "\[ \t\]"
+
+# Regression test for PR31900.
+setup_kfail "gdb/31900" *-*-*
+set val1 ns::A::val1
+gdb_test_lines "maint print objfiles" \
+    "val1 has a parent" \
+    [multi_line \
+	 "" \
+	 "$re_ws+qualified:$re_ws+$val1" \
+	 ".*"]
+
+gdb_test "print $val1" " = $val1"


More information about the Gdb-cvs mailing list