[1/5,gdb/testsuite] Add gdb.dwarf2/enum-type-c++.exp, regression test for PR31900.
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
Commit Message
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.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31900
---
gdb/testsuite/gdb.dwarf2/enum-type-c++.cc | 29 ++++++++++++++
gdb/testsuite/gdb.dwarf2/enum-type-c++.exp | 44 ++++++++++++++++++++++
2 files changed, 73 insertions(+)
create mode 100644 gdb/testsuite/gdb.dwarf2/enum-type-c++.cc
create mode 100644 gdb/testsuite/gdb.dwarf2/enum-type-c++.exp
base-commit: 4290b2c07e2d9bc1e1661a4ad5e343e3eb307770
Comments
>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
Tom> Add a test-case gdb.dwarf2/enum-type-c++.exp that contains a regression test
Tom> for this problem that doesn't rely on expansion state or
Tom> -feliminate-unused-debug-types, but simply tests for the root cause by
Tom> grepping for ns::A::val1 in the output of "maint print objfile".
Ok.
Approved-By: Tom Tromey <tom@tromey.com>
Tom
On 9/12/24 8:52 AM, Tom de Vries wrote:
> 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.
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31900
> ---
> gdb/testsuite/gdb.dwarf2/enum-type-c++.cc | 29 ++++++++++++++
> gdb/testsuite/gdb.dwarf2/enum-type-c++.exp | 44 ++++++++++++++++++++++
> 2 files changed, 73 insertions(+)
> create mode 100644 gdb/testsuite/gdb.dwarf2/enum-type-c++.cc
> create mode 100644 gdb/testsuite/gdb.dwarf2/enum-type-c++.exp
>
> 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"
>
> base-commit: 4290b2c07e2d9bc1e1661a4ad5e343e3eb307770
Hi Tom
The test introduced by this patch fails with clang with the attached log.
Some of the fails come from later patches, but "print ns::A::val1" fails
ever since this patch.
On 9/16/24 21:21, Guinevere Larsen wrote:
> Hi Tom
>
> The test introduced by this patch fails with clang with the attached log.
>
> Some of the fails come from later patches, but "print ns::A::val1" fails
> ever since this patch.
Hi Gwen,
thanks for reporting this.
I'm working on a fix, but a more complicated one that just bailing out
for clang, so it's taking a bit longer.
Thanks,
- Tom
new file mode 100644
@@ -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;
new file mode 100644
@@ -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"