* [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
@ 2021-01-25 12:24 Tom de Vries
2021-01-25 12:52 ` Bernd Edlinger
0 siblings, 1 reply; 12+ messages in thread
From: Tom de Vries @ 2021-01-25 12:24 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey
Hi,
While looking into a failure in gdb.go/package.exp with gcc-11, I noticed that
gdb shows some complaints when loading the executable (also with gcc-10, where
the test-case passes):
...
$ gdb -batch -iex "set complaints 100" package.10 -ex start
During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
Temporary breakpoint 1 at 0x402ae6: file gdb.go/package1.go, line 8.
During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
During symbol reading: Invalid .debug_rnglists data (no base address)
...
Fix this by using as_unsigned () to read DW_AT_ranges in the partial DIE
reader, similar to how that is done in dwarf2_get_pc_bounds.
Tested on x86_64-linux.
Any comments?
Thanks,
- Tom
[gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
gdb/ChangeLog:
2021-01-25 Tom de Vries <tdevries@suse.de>
* dwarf2/read.c (partial_die_info::read): Use as_unsigned () for
DW_AT_ranges.
gdb/testsuite/ChangeLog:
2021-01-25 Tom de Vries <tdevries@suse.de>
* gdb.dwarf2/dw2-ranges-psym.exp (gdb_load_no_complaints): New proc.
* lib/gdb.exp: Use gdb_load_no_complaints.
---
gdb/dwarf2/read.c | 2 +-
gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp | 5 +++-
gdb/testsuite/lib/gdb.exp | 36 ++++++++++++++++++++++++++++
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 309ff8331e7..5191d697ec7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -19810,7 +19810,7 @@ partial_die_info::read (const struct die_reader_specs *reader,
/* It would be nice to reuse dwarf2_get_pc_bounds here,
but that requires a full DIE, so instead we just
reimplement it. */
- unsigned int ranges_offset = (attr.constant_value (0)
+ unsigned int ranges_offset = (attr.as_unsigned ()
+ (need_ranges_base
? cu->ranges_base
: 0));
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp
index 72966aff820..3ad2d1c567c 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-psym.exp
@@ -120,11 +120,14 @@ Dwarf::assemble $asm_file {
}
}
-if { [prepare_for_testing "failed to prepare" ${testfile} \
+if { [build_executable "failed to prepare" ${testfile} \
[list $srcfile $srcfile2 $asm_file] {nodebug}] } {
return -1
}
+clean_restart
+gdb_load_no_complaints $binfile
+
if ![runto_main] {
return -1
}
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 03653ab1a7f..2a952c6146f 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5095,6 +5095,42 @@ proc gdb_load { arg } {
return 0
}
+#
+# gdb_load_no_complaints -- As gdb_load, but in addition verifies that
+# loading caused no symbol reading complaints.
+#
+proc gdb_load_no_complaints { arg } {
+ global gdb_prompt gdb_file_cmd_msg decimal
+
+ # Save current setting of complaints.
+ set save ""
+ set show_complaints_re \
+ "Max number of complaints about incorrect symbols is ($decimal)\\."
+ gdb_test_multiple "show complaints" "" {
+ -re -wrap $show_complaints_re {
+ set save $expect_out(1,string)
+ }
+ }
+
+ # Fall back to regular gdb_load if we couldn't get the current setting
+ # of complaints.
+ if { $save == "" } {
+ return gdb_load $arg
+ }
+
+ # Temporarily set complaint to a small non-zero number.
+ gdb_test_no_output "set complaints 5" ""
+
+ gdb_load $arg
+
+ # Verify that there were no complaints.
+ set re "^Reading symbols from \[^\r\n\]*\r\n$gdb_prompt $"
+ gdb_assert {[regexp $re $gdb_file_cmd_msg]} "No complaints"
+
+ # Restore saved setting of complaints.
+ gdb_test_no_output "set complaints $save" ""
+}
+
# gdb_reload -- load a file into the target. Called before "running",
# either the first time or after already starting the program once,
# for remote targets. Most files that override gdb_load should now
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 12:24 [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE Tom de Vries
@ 2021-01-25 12:52 ` Bernd Edlinger
2021-01-25 15:27 ` Simon Marchi via Gdb-patches
0 siblings, 1 reply; 12+ messages in thread
From: Bernd Edlinger @ 2021-01-25 12:52 UTC (permalink / raw)
To: Tom de Vries, gdb-patches; +Cc: Tom Tromey
[-- Attachment #1: Type: text/plain, Size: 1078 bytes --]
On 1/25/21 1:24 PM, Tom de Vries wrote:
> Hi,
>
> While looking into a failure in gdb.go/package.exp with gcc-11, I noticed that
> gdb shows some complaints when loading the executable (also with gcc-10, where
> the test-case passes):
> ...
> $ gdb -batch -iex "set complaints 100" package.10 -ex start
> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
> Temporary breakpoint 1 at 0x402ae6: file gdb.go/package1.go, line 8.
> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
> During symbol reading: Invalid .debug_rnglists data (no base address)
> ...
>
> Fix this by using as_unsigned () to read DW_AT_ranges in the partial DIE
> reader, similar to how that is done in dwarf2_get_pc_bounds.
>
> Tested on x86_64-linux.
>
> Any comments?
>
Oh, interesting.
This is exactly what I have posted here:
https://sourceware.org/pipermail/gdb-patches/2021-January/174660.html
but my test case shows the regression in the partial symbols.
Maybe you can take my test case and merge it to your patch?
Thanks
Bernd.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Fix-partial-symbols.patch --]
[-- Type: text/x-patch; name="0001-Fix-partial-symbols.patch", Size: 4460 bytes --]
From 338f196f9cb4da8b85e42f435424f1c6dc396b36 Mon Sep 17 00:00:00 2001
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
Date: Sat, 28 Nov 2020 17:29:18 +0100
Subject: [PATCH] Fix partial symbols
The DW_AT_ranges attribute is of type DW_FORM_sec_offset
or DW_FORM_rnglistx.
But the function attribute attribute::constant_value () does only
handle DW_FORM_sdata, DW_FORM_implicit_const, DW_FORM_udata
DW_FORM_data1, DW_FORM_data2, DW_FORM_data4, DW_FORM_data8
and returns the default value for anything else.
Therefore the wrong range is parsed.
Fixes: 529908cbd0a ("Remove DW_UNSND")
gdb:
2021-01-03 Bernd Edlinger <bernd.edlinger@hotmail.de>
* dwarf2/read.c (partial_die_info::read): Fix DW_AT_ranges.
gdb/testsuite:
2021-01-03 Bernd Edlinger <bernd.edlinger@hotmail.de>
* gdb.cp/step-and-next-psymtab.exp: New test.
* gdb.cp/step-and-next-psymtab.cc: New test.
---
gdb/dwarf2/read.c | 2 +-
gdb/testsuite/gdb.cp/step-and-next-psymtab.cc | 27 ++++++++++++++++++++
gdb/testsuite/gdb.cp/step-and-next-psymtab.exp | 34 ++++++++++++++++++++++++++
3 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.cp/step-and-next-psymtab.cc
create mode 100644 gdb/testsuite/gdb.cp/step-and-next-psymtab.exp
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 309ff83..5191d69 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -19810,7 +19810,7 @@ struct type *
/* It would be nice to reuse dwarf2_get_pc_bounds here,
but that requires a full DIE, so instead we just
reimplement it. */
- unsigned int ranges_offset = (attr.constant_value (0)
+ unsigned int ranges_offset = (attr.as_unsigned ()
+ (need_ranges_base
? cu->ranges_base
: 0));
diff --git a/gdb/testsuite/gdb.cp/step-and-next-psymtab.cc b/gdb/testsuite/gdb.cp/step-and-next-psymtab.cc
new file mode 100644
index 0000000..1bb724b
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/step-and-next-psymtab.cc
@@ -0,0 +1,27 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2021 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/>. */
+
+#include "step-and-next-inline.h"
+
+int
+get_alias_set1 (tree *t)
+{
+ if (t != NULL
+ && TREE_TYPE (t).z != 1)
+ return 0;
+ return 1;
+}
diff --git a/gdb/testsuite/gdb.cp/step-and-next-psymtab.exp b/gdb/testsuite/gdb.cp/step-and-next-psymtab.exp
new file mode 100644
index 0000000..2268f16
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/step-and-next-psymtab.exp
@@ -0,0 +1,34 @@
+# Copyright 2021 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/>.
+
+standard_testfile step-and-next-inline.cc .cc
+
+if [get_compiler_info "c++"] {
+ unsupported "couldn't find a valid c++ compiler"
+ return -1
+}
+
+set options {c++ debug nowarnings optimize=-O2}
+# avoid DW_TAG_compile_unit with low_pc != 0 (gcc-8 and earlier)
+lappend options additional_flags=-ffunction-sections
+
+set sources [list $srcfile $srcfile2]
+
+if { [prepare_for_testing "failed to prepare" $testfile $sources $options] } {
+ return -1
+}
+
+# there are 4 tree_check instances not 3
+gdb_test "b tree_check" ".*Breakpoint .* \\(4 locations\\).*" "test1"
--
1.9.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 12:52 ` Bernd Edlinger
@ 2021-01-25 15:27 ` Simon Marchi via Gdb-patches
2021-01-25 15:37 ` Tom de Vries
0 siblings, 1 reply; 12+ messages in thread
From: Simon Marchi via Gdb-patches @ 2021-01-25 15:27 UTC (permalink / raw)
To: Bernd Edlinger, Tom de Vries, gdb-patches; +Cc: Tom Tromey
On 2021-01-25 7:52 a.m., Bernd Edlinger wrote:
> On 1/25/21 1:24 PM, Tom de Vries wrote:
>> Hi,
>>
>> While looking into a failure in gdb.go/package.exp with gcc-11, I noticed that
>> gdb shows some complaints when loading the executable (also with gcc-10, where
>> the test-case passes):
>> ...
>> $ gdb -batch -iex "set complaints 100" package.10 -ex start
>> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
>> Temporary breakpoint 1 at 0x402ae6: file gdb.go/package1.go, line 8.
>> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
>> During symbol reading: Invalid .debug_rnglists data (no base address)
>> ...
>>
>> Fix this by using as_unsigned () to read DW_AT_ranges in the partial DIE
>> reader, similar to how that is done in dwarf2_get_pc_bounds.
>>
>> Tested on x86_64-linux.
>>
>> Any comments?
>>
>
> Oh, interesting.
>
> This is exactly what I have posted here:
>
> https://sourceware.org/pipermail/gdb-patches/2021-January/174660.html
>
> but my test case shows the regression in the partial symbols.
>
>
>
> Maybe you can take my test case and merge it to your patch?
>
>
> Thanks
> Bernd.
>
Haha, I also wrote the same patch:
https://sourceware.org/pipermail/gdb-patches/2021-January/175225.html
Either of your patches is fine with me. Note that the test that I add
later in my series (written with the DWARF assembler) triggers the bug
as well.
Simon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 15:27 ` Simon Marchi via Gdb-patches
@ 2021-01-25 15:37 ` Tom de Vries
2021-01-25 15:47 ` Bernd Edlinger
0 siblings, 1 reply; 12+ messages in thread
From: Tom de Vries @ 2021-01-25 15:37 UTC (permalink / raw)
To: Simon Marchi, Bernd Edlinger, gdb-patches; +Cc: Tom Tromey
On 1/25/21 4:27 PM, Simon Marchi wrote:
>
>
> On 2021-01-25 7:52 a.m., Bernd Edlinger wrote:
>> On 1/25/21 1:24 PM, Tom de Vries wrote:
>>> Hi,
>>>
>>> While looking into a failure in gdb.go/package.exp with gcc-11, I noticed that
>>> gdb shows some complaints when loading the executable (also with gcc-10, where
>>> the test-case passes):
>>> ...
>>> $ gdb -batch -iex "set complaints 100" package.10 -ex start
>>> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
>>> Temporary breakpoint 1 at 0x402ae6: file gdb.go/package1.go, line 8.
>>> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
>>> During symbol reading: Invalid .debug_rnglists data (no base address)
>>> ...
>>>
>>> Fix this by using as_unsigned () to read DW_AT_ranges in the partial DIE
>>> reader, similar to how that is done in dwarf2_get_pc_bounds.
>>>
>>> Tested on x86_64-linux.
>>>
>>> Any comments?
>>>
>>
>> Oh, interesting.
>>
>> This is exactly what I have posted here:
>>
>> https://sourceware.org/pipermail/gdb-patches/2021-January/174660.html
>>
>> but my test case shows the regression in the partial symbols.
>>
>>
>>
>> Maybe you can take my test case and merge it to your patch?
>>
>>
I've looked at it, but it's optimized code, which may be fragile in
terms of number of break locations. I wouldn't mind a dwarf assembly
version of that one though.
>> Thanks
>> Bernd.
>>
>
> Haha, I also wrote the same patch:
>
> https://sourceware.org/pipermail/gdb-patches/2021-January/175225.html
>
Heh, this starts to sound a lot like a "how many software engineers does
it take to fix one line of code" kind of joke :)
> Either of your patches is fine with me. Note that the test that I add
> later in my series (written with the DWARF assembler) triggers the bug
> as well.
Ah, that's good to know.
I've push mine, and added you both as author in the ChangeLog.
Thanks,
- Tom
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 15:37 ` Tom de Vries
@ 2021-01-25 15:47 ` Bernd Edlinger
2021-01-25 16:36 ` Simon Marchi via Gdb-patches
0 siblings, 1 reply; 12+ messages in thread
From: Bernd Edlinger @ 2021-01-25 15:47 UTC (permalink / raw)
To: Tom de Vries, Simon Marchi, gdb-patches; +Cc: Tom Tromey
On 1/25/21 4:37 PM, Tom de Vries wrote:
> On 1/25/21 4:27 PM, Simon Marchi wrote:
>>
>>
>> On 2021-01-25 7:52 a.m., Bernd Edlinger wrote:
>>> On 1/25/21 1:24 PM, Tom de Vries wrote:
>>>> Hi,
>>>>
>>>> While looking into a failure in gdb.go/package.exp with gcc-11, I noticed that
>>>> gdb shows some complaints when loading the executable (also with gcc-10, where
>>>> the test-case passes):
>>>> ...
>>>> $ gdb -batch -iex "set complaints 100" package.10 -ex start
>>>> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
>>>> Temporary breakpoint 1 at 0x402ae6: file gdb.go/package1.go, line 8.
>>>> During symbol reading: Attribute value is not a constant (DW_FORM_sec_offset)
>>>> During symbol reading: Invalid .debug_rnglists data (no base address)
>>>> ...
>>>>
>>>> Fix this by using as_unsigned () to read DW_AT_ranges in the partial DIE
>>>> reader, similar to how that is done in dwarf2_get_pc_bounds.
>>>>
>>>> Tested on x86_64-linux.
>>>>
>>>> Any comments?
>>>>
>>>
>>> Oh, interesting.
>>>
>>> This is exactly what I have posted here:
>>>
>>> https://sourceware.org/pipermail/gdb-patches/2021-January/174660.html
>>>
>>> but my test case shows the regression in the partial symbols.
>>>
>>>
>>>
>>> Maybe you can take my test case and merge it to your patch?
>>>
>>>
>
> I've looked at it, but it's optimized code, which may be fragile in
> terms of number of break locations. I wouldn't mind a dwarf assembly
> version of that one though.
>
Yes, unfortunately I have not any experience with writing such assembly
tests, but I am always impressed when one of you does it though :-)
Nevertheless, the test case seems to be stable from gcc-4.8 .. gcc-11,
that it fails without the patch and passes with the patch.
So is it okay to push my partial symbols test as-is?
Thanks
Bernd.
>>> Thanks
>>> Bernd.
>>>
>>
>> Haha, I also wrote the same patch:
>>
>> https://sourceware.org/pipermail/gdb-patches/2021-January/175225.html
>>
>
> Heh, this starts to sound a lot like a "how many software engineers does
> it take to fix one line of code" kind of joke :)
>
>> Either of your patches is fine with me. Note that the test that I add
>> later in my series (written with the DWARF assembler) triggers the bug
>> as well.
>
> Ah, that's good to know.
>
> I've push mine, and added you both as author in the ChangeLog.
>
> Thanks,
> - Tom
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 15:47 ` Bernd Edlinger
@ 2021-01-25 16:36 ` Simon Marchi via Gdb-patches
2021-01-25 17:42 ` Bernd Edlinger
0 siblings, 1 reply; 12+ messages in thread
From: Simon Marchi via Gdb-patches @ 2021-01-25 16:36 UTC (permalink / raw)
To: Bernd Edlinger, Tom de Vries, gdb-patches; +Cc: Tom Tromey
> Yes, unfortunately I have not any experience with writing such assembly
> tests, but I am always impressed when one of you does it though :-)
>
> Nevertheless, the test case seems to be stable from gcc-4.8 .. gcc-11,
> that it fails without the patch and passes with the patch.
>
> So is it okay to push my partial symbols test as-is?
My patch here adds a test that uses DW_FORM_sec_offset to point
to a .debug_rnglists (DWARF5) section. Maybe that's sufficient,
but if not I could probably do a DWARF4 equivalent.
https://sourceware.org/pipermail/gdb-patches/2021-January/175229.html
Simon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 16:36 ` Simon Marchi via Gdb-patches
@ 2021-01-25 17:42 ` Bernd Edlinger
2021-01-25 18:12 ` Simon Marchi via Gdb-patches
0 siblings, 1 reply; 12+ messages in thread
From: Bernd Edlinger @ 2021-01-25 17:42 UTC (permalink / raw)
To: Simon Marchi, Tom de Vries, gdb-patches; +Cc: Tom Tromey
On 1/25/21 5:36 PM, Simon Marchi wrote:
>> Yes, unfortunately I have not any experience with writing such assembly
>> tests, but I am always impressed when one of you does it though :-)
>>
>> Nevertheless, the test case seems to be stable from gcc-4.8 .. gcc-11,
>> that it fails without the patch and passes with the patch.
>>
>> So is it okay to push my partial symbols test as-is?
>
> My patch here adds a test that uses DW_FORM_sec_offset to point
> to a .debug_rnglists (DWARF5) section. Maybe that's sufficient,
> but if not I could probably do a DWARF4 equivalent.
>
> https://sourceware.org/pipermail/gdb-patches/2021-January/175229.html
>
Yeah, the hardest part on a one-line change like this is always the test case.
So, I tried this patch on current trunk, but it fails:
Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp ...
ERROR: Couldn't load rnglists-multiple-cus-dw32 into GDB (GDB internal error).
ERROR: Couldn't load rnglists-multiple-cus-dw64 into GDB (GDB internal error).
Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp ...
FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=false: p/x &foo
FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=true: p/x &foo
This probably means that your test tests more than this single-line change alone?
I always thought that the partial symbols are replaced by the
full symbols as soon as the first item from the CU is accessed, say "main".
Can you explain how that can be?
I was never able to get a reproducer for partial symbols with only one CU.
Bernd.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 17:42 ` Bernd Edlinger
@ 2021-01-25 18:12 ` Simon Marchi via Gdb-patches
2021-01-25 18:53 ` Bernd Edlinger
0 siblings, 1 reply; 12+ messages in thread
From: Simon Marchi via Gdb-patches @ 2021-01-25 18:12 UTC (permalink / raw)
To: Bernd Edlinger, Tom de Vries, gdb-patches; +Cc: Tom Tromey
On 2021-01-25 12:42 p.m., Bernd Edlinger wrote:
> On 1/25/21 5:36 PM, Simon Marchi wrote:
>>> Yes, unfortunately I have not any experience with writing such assembly
>>> tests, but I am always impressed when one of you does it though :-)
>>>
>>> Nevertheless, the test case seems to be stable from gcc-4.8 .. gcc-11,
>>> that it fails without the patch and passes with the patch.
>>>
>>> So is it okay to push my partial symbols test as-is?
>>
>> My patch here adds a test that uses DW_FORM_sec_offset to point
>> to a .debug_rnglists (DWARF5) section. Maybe that's sufficient,
>> but if not I could probably do a DWARF4 equivalent.
>>
>> https://sourceware.org/pipermail/gdb-patches/2021-January/175229.html
>>
>
> Yeah, the hardest part on a one-line change like this is always the test case.
>
> So, I tried this patch on current trunk, but it fails:
>
> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp ...
> ERROR: Couldn't load rnglists-multiple-cus-dw32 into GDB (GDB internal error).
> ERROR: Couldn't load rnglists-multiple-cus-dw64 into GDB (GDB internal error).
> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp ...
> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=false: p/x &foo
> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=true: p/x &foo
>
> This probably means that your test tests more than this single-line change alone?
Hmm, with current master (so with Tom's patch merged),
gdb.dwarf2/rnglists-sec-offset.exp passes for me.
But gdb.dwarf2/rnglists-multiple-cus.exp is expected to fail if you don't
have the other patches in my series.
> I always thought that the partial symbols are replaced by the
> full symbols as soon as the first item from the CU is accessed, say "main".
> Can you explain how that can be?
> I was never able to get a reproducer for partial symbols with only one CU.
The bug fixed by this patch triggers as soon as you have a function
(DW_TAG_subprogram) with a DW_AT_ranges, I don't think it matters whether
there is one or more CUs. But perhaps it's difficult to force the compiler
to emit a function with DW_AT_ranges (so, with a non-contiguous range) when
using a single CU.
Simon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 18:12 ` Simon Marchi via Gdb-patches
@ 2021-01-25 18:53 ` Bernd Edlinger
2021-01-25 19:20 ` Bernd Edlinger
2021-01-26 1:52 ` Simon Marchi via Gdb-patches
0 siblings, 2 replies; 12+ messages in thread
From: Bernd Edlinger @ 2021-01-25 18:53 UTC (permalink / raw)
To: Simon Marchi, Tom de Vries, gdb-patches; +Cc: Tom Tromey
[-- Attachment #1: Type: text/plain, Size: 3171 bytes --]
On 1/25/21 7:12 PM, Simon Marchi wrote:
>
>
> On 2021-01-25 12:42 p.m., Bernd Edlinger wrote:
>> On 1/25/21 5:36 PM, Simon Marchi wrote:
>>>> Yes, unfortunately I have not any experience with writing such assembly
>>>> tests, but I am always impressed when one of you does it though :-)
>>>>
>>>> Nevertheless, the test case seems to be stable from gcc-4.8 .. gcc-11,
>>>> that it fails without the patch and passes with the patch.
>>>>
>>>> So is it okay to push my partial symbols test as-is?
>>>
>>> My patch here adds a test that uses DW_FORM_sec_offset to point
>>> to a .debug_rnglists (DWARF5) section. Maybe that's sufficient,
>>> but if not I could probably do a DWARF4 equivalent.
>>>
>>> https://sourceware.org/pipermail/gdb-patches/2021-January/175229.html
>>>
>>
>> Yeah, the hardest part on a one-line change like this is always the test case.
>>
>> So, I tried this patch on current trunk, but it fails:
>>
>> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp ...
>> ERROR: Couldn't load rnglists-multiple-cus-dw32 into GDB (GDB internal error).
>> ERROR: Couldn't load rnglists-multiple-cus-dw64 into GDB (GDB internal error).
>> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp ...
>> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=false: p/x &foo
>> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=true: p/x &foo
>>
>> This probably means that your test tests more than this single-line change alone?
>
> Hmm, with current master (so with Tom's patch merged),
> gdb.dwarf2/rnglists-sec-offset.exp passes for me.
>
That will probably need investigation.
Let's first check if I applied the corrrect test case,
see attached patch.txt.
tried to do "readelf --debug-dump rnglists-sec-offset-dw32" and
"readelf --debug-dump rnglists-sec-offset-dw64"
I used GNU readelf (GNU Binutils) 2.35.1
I see a warning:
readelf: Warnung: The .debug_rnglists section contains unsupported offset entry count: 2.
what does that mean?
Doesn't that indicate that the debug-info somehow wrong?
> But gdb.dwarf2/rnglists-multiple-cus.exp is expected to fail if you don't
> have the other patches in my series.
>
>> I always thought that the partial symbols are replaced by the
>> full symbols as soon as the first item from the CU is accessed, say "main".
>> Can you explain how that can be?
>> I was never able to get a reproducer for partial symbols with only one CU.
>
> The bug fixed by this patch triggers as soon as you have a function
> (DW_TAG_subprogram) with a DW_AT_ranges, I don't think it matters whether
> there is one or more CUs. But perhaps it's difficult to force the compiler
> to emit a function with DW_AT_ranges (so, with a non-contiguous range) when
> using a single CU.
>
It happens pretty reliably when you have a function that contains an error
handling that looks obvously "unlinkely" to the compiler, because it is guarded
by an if-condition and calls abort(), while there are also code paths that
don't call about. The parts that call abort are then in a separate cold section.
Bernd.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 6303 bytes --]
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 7462890..aba4afb 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -473,7 +473,8 @@ namespace eval Dwarf {
}
DW_FORM_ref_udata -
- DW_FORM_udata {
+ DW_FORM_udata -
+ DW_FORM_rnglistx {
_op .uleb128 $value
}
@@ -1115,8 +1116,16 @@ namespace eval Dwarf {
}
define_label $start_label
_op .2byte $_cu_version Version
- _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
- _op .byte $_cu_addr_size "Pointer size"
+
+ # The CU header for DWARF 4 and 5 are slightly different.
+ if { $_cu_version == 5 } {
+ _op .byte 0x1 "DW_UT_compile"
+ _op .byte $_cu_addr_size "Pointer size"
+ _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
+ } else {
+ _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
+ _op .byte $_cu_addr_size "Pointer size"
+ }
_defer_output $_abbrev_section {
define_label $my_abbrevs
@@ -1306,6 +1315,178 @@ namespace eval Dwarf {
uplevel $body
}
+ # Emit a DWARF .debug_rnglists section.
+ #
+ # The target address size is based on the current target's address size.
+ #
+ # There is one mandatory positional argument, BODY, which must be Tcl code
+ # that emits the content of the section. It is evaluated in the caller's
+ # context.
+ #
+ # The following option can be used:
+ #
+ # - -is-64 true|false: Whether to use 64-bit DWARF instead of 32-bit DWARF.
+ # The default is 32-bit.
+
+ proc rnglists { args } {
+ variable _debug_rnglists_addr_size
+ variable _debug_rnglists_offset_size
+ variable _debug_rnglists_is_64_dwarf
+
+ parse_args {{"is-64" "false"}}
+
+ if { [llength $args] != 1 } {
+ error "rnglists proc expects one positional argument (body)"
+ }
+
+ lassign $args body
+
+ if [is_64_target] {
+ set _debug_rnglists_addr_size 8
+ } else {
+ set _debug_rnglists_addr_size 4
+ }
+
+ if { ${is-64} } {
+ set _debug_rnglists_offset_size 8
+ set _debug_rnglists_is_64_dwarf true
+ } else {
+ set _debug_rnglists_offset_size 4
+ set _debug_rnglists_is_64_dwarf false
+ }
+
+ _section ".debug_rnglists"
+
+ # Count of tables in the section.
+ variable _debug_rnglists_table_count 0
+
+ # Compute the label name for list at index LIST_IDX, for the current
+ # table.
+
+ proc _compute_list_label { list_idx } {
+ variable _debug_rnglists_table_count
+
+ return ".Lrnglists_table_${_debug_rnglists_table_count}_list_${list_idx}"
+ }
+
+ # Generate one table (header + offset array + range lists).
+ #
+ # Accepts one positional argument, BODY. BODY may call the LIST_
+ # procedure to generate rnglists.
+ #
+ # The -post-header-label option can be used to define a label just after
+ # the header of the table. This is the label that a DW_AT_rnglists_base
+ # attribute will usually refer to.
+
+ proc table { args } {
+ variable _debug_rnglists_table_count
+ variable _debug_rnglists_addr_size
+ variable _debug_rnglists_offset_size
+ variable _debug_rnglists_is_64_dwarf
+
+ parse_args {{post-header-label ""}}
+
+ if { [llength $args] != 1 } {
+ error "table proc expects one positional argument (body)"
+ }
+
+ lassign $args body
+
+ # Generate one range list.
+ #
+ # BODY may call the various procs defined below to generate list entries.
+ # They correspond to the range list entry kinds described in section 2.17.3
+ # of the DWARF 5 spec.
+ #
+ # To define a label pointing to the beginning of the list, use
+ # the conventional way of declaring and defining labels:
+ #
+ # declare_labels the_list
+ #
+ # the_list: list_ {
+ # ...
+ # }
+
+ proc list_ { body } {
+ variable _debug_rnglists_list_count
+
+ # Define a label for this list. It is used to build the offset
+ # array later.
+ set list_label [_compute_list_label $_debug_rnglists_list_count]
+ define_label $list_label
+
+ # Emit a DW_RLE_start_end entry.
+
+ proc start_end { start end } {
+ variable _debug_rnglists_addr_size
+
+ _op .byte 0x06 "DW_RLE_start_end"
+ _op .${_debug_rnglists_addr_size}byte $start "start"
+ _op .${_debug_rnglists_addr_size}byte $end "end"
+ }
+
+ uplevel $body
+
+ # Emit end of list.
+ _op .byte 0x00 "DW_RLE_end_of_list"
+
+ incr _debug_rnglists_list_count
+ }
+
+ # Count of lists in the table.
+ variable _debug_rnglists_list_count 0
+
+ # Generate the lists ops first, because we need to know how many
+ # lists there are to generate the header and offset table.
+ set lists_ops [_defer_to_string {
+ uplevel $body
+ }]
+
+ set post_unit_len_label \
+ [_compute_label "rnglists_table_${_debug_rnglists_table_count}_post_unit_len"]
+ set post_header_label \
+ [_compute_label "rnglists_table_${_debug_rnglists_table_count}_post_header"]
+ set table_end_label \
+ [_compute_label "rnglists_table_${_debug_rnglists_table_count}_end"]
+
+ # Emit the table header.
+ if { $_debug_rnglists_is_64_dwarf } {
+ _op .4byte 0xffffffff "unit length 1/2"
+ _op .8byte "$table_end_label - $post_unit_len_label" "unit length 2/2"
+ } else {
+ _op .4byte "$table_end_label - $post_unit_len_label" "unit length"
+ }
+
+ define_label $post_unit_len_label
+
+ _op .2byte 5 "dwarf version"
+ _op .byte $_debug_rnglists_addr_size "address size"
+ _op .byte 0 "segment selector size"
+ _op .4byte "$_debug_rnglists_list_count" "offset entry count"
+
+ define_label $post_header_label
+
+ # Define the user post-header label, if provided.
+ if { ${post-header-label} != "" } {
+ define_label ${post-header-label}
+ }
+
+ # Emit the offset array.
+ for {set list_idx 0} {$list_idx < $_debug_rnglists_list_count} {incr list_idx} {
+ set list_label [_compute_list_label $list_idx]
+ _op .${_debug_rnglists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx"
+ }
+
+ # Emit the actual list data.
+ _emit "$lists_ops"
+
+ define_label $table_end_label
+
+ incr _debug_rnglists_table_count
+ }
+
+ uplevel $body
+ }
# Emit a DWARF .debug_line unit.
# OPTIONS is a list with an even number of elements containing
[-- Attachment #3: rnglists-sec-offset-dw32.txt --]
[-- Type: text/plain, Size: 1567 bytes --]
Inhalt der .debug_info-Sektion:
Compilation Unit @ offset 0x0:
Länge: 0x17 (32-bit)
Version: 5
Abbrev Offset: 0x0
Zeigergröße: 8
<0><c>: Zahl abkürzen: 2 (DW_TAG_compile_unit)
<d> DW_AT_ranges : 0x14
<1><11>: Zahl abkürzen: 3 (DW_TAG_subprogram)
<12> DW_AT_name : foo
<16> DW_AT_ranges : 0x26
<1><1a>: Abbrev Number: 0
Inhalt der .debug_abbrev-Sektion:
Number TAG (0x0)
2 DW_TAG_compile_unit [hat Kinder]
DW_AT_ranges DW_FORM_sec_offset
DW_AT value: 0 DW_FORM value: 0
3 DW_TAG_subprogram [keine Kinder]
DW_AT_name DW_FORM_string
DW_AT_ranges DW_FORM_sec_offset
DW_AT value: 0 DW_FORM value: 0
Raw dump of debug contents of section .debug_line:
Versatz: 0x0
Länge: 25
DWARF Version: 3
Länge des Prologs: 19
Minimale Instruktionslänge: 1
Initialer Wert von ‚is_stmt‛: 1
Zeilenbasis: -5
Zeilenreichweite: 14
Opcode-Basis: 13
Opcodes:
Opcode 1 has 0 args
Opcode 2 has 1 arg
Opcode 3 has 1 arg
Opcode 4 has 1 arg
Opcode 5 has 1 arg
Opcode 6 has 0 args
Opcode 7 has 0 args
Opcode 8 has 0 args
Opcode 9 has 1 arg
Opcode 10 has 0 args
Opcode 11 has 0 args
Opcode 12 has 1 arg
Die Verzeichnistabelle ist leer.
Die Dateinamentabelle ist leer.
No Line Number Statements.
readelf: Warnung: The .debug_rnglists section contains unsupported offset entry count: 2.
[-- Attachment #4: rnglists-sec-offset-dw64.txt --]
[-- Type: text/plain, Size: 1569 bytes --]
Inhalt der .debug_info-Sektion:
Compilation Unit @ offset 0x0:
Länge: 0x23 (64-bit)
Version: 5
Abbrev Offset: 0x0
Zeigergröße: 8
<0><18>: Zahl abkürzen: 2 (DW_TAG_compile_unit)
<19> DW_AT_ranges : 0x24
<1><21>: Zahl abkürzen: 3 (DW_TAG_subprogram)
<22> DW_AT_name : foo
<26> DW_AT_ranges : 0x36
<1><2e>: Abbrev Number: 0
Inhalt der .debug_abbrev-Sektion:
Number TAG (0x0)
2 DW_TAG_compile_unit [hat Kinder]
DW_AT_ranges DW_FORM_sec_offset
DW_AT value: 0 DW_FORM value: 0
3 DW_TAG_subprogram [keine Kinder]
DW_AT_name DW_FORM_string
DW_AT_ranges DW_FORM_sec_offset
DW_AT value: 0 DW_FORM value: 0
Raw dump of debug contents of section .debug_line:
Versatz: 0x0
Länge: 25
DWARF Version: 3
Länge des Prologs: 19
Minimale Instruktionslänge: 1
Initialer Wert von ‚is_stmt‛: 1
Zeilenbasis: -5
Zeilenreichweite: 14
Opcode-Basis: 13
Opcodes:
Opcode 1 has 0 args
Opcode 2 has 1 arg
Opcode 3 has 1 arg
Opcode 4 has 1 arg
Opcode 5 has 1 arg
Opcode 6 has 0 args
Opcode 7 has 0 args
Opcode 8 has 0 args
Opcode 9 has 1 arg
Opcode 10 has 0 args
Opcode 11 has 0 args
Opcode 12 has 1 arg
Die Verzeichnistabelle ist leer.
Die Dateinamentabelle ist leer.
No Line Number Statements.
readelf: Warnung: The .debug_rnglists section contains unsupported offset entry count: 2.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 18:53 ` Bernd Edlinger
@ 2021-01-25 19:20 ` Bernd Edlinger
2021-01-26 1:52 ` Simon Marchi via Gdb-patches
1 sibling, 0 replies; 12+ messages in thread
From: Bernd Edlinger @ 2021-01-25 19:20 UTC (permalink / raw)
To: Simon Marchi, Tom de Vries, gdb-patches; +Cc: Tom Tromey
[-- Attachment #1: Type: text/plain, Size: 518 bytes --]
On 1/25/21 7:53 PM, Bernd Edlinger wrote:
> see attached patch.txt.
Oops, that patch.txt was incomplete.
please find the correct patch here.
>
> It happens pretty reliably when you have a function that contains an error
> handling that looks obvously "unlinkely" to the compiler, because it is guarded
I meant, "obviously unlikely".
> by an if-condition and calls abort(), while there are also code paths that
> don't call about. The parts that call abort are then in a separate cold section.
>
>
> Bernd.
>
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 11964 bytes --]
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 7462890..aba4afb 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -473,7 +473,8 @@ namespace eval Dwarf {
}
DW_FORM_ref_udata -
- DW_FORM_udata {
+ DW_FORM_udata -
+ DW_FORM_rnglistx {
_op .uleb128 $value
}
@@ -1115,8 +1116,16 @@ namespace eval Dwarf {
}
define_label $start_label
_op .2byte $_cu_version Version
- _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
- _op .byte $_cu_addr_size "Pointer size"
+
+ # The CU header for DWARF 4 and 5 are slightly different.
+ if { $_cu_version == 5 } {
+ _op .byte 0x1 "DW_UT_compile"
+ _op .byte $_cu_addr_size "Pointer size"
+ _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
+ } else {
+ _op .${_cu_offset_size}byte $my_abbrevs Abbrevs
+ _op .byte $_cu_addr_size "Pointer size"
+ }
_defer_output $_abbrev_section {
define_label $my_abbrevs
@@ -1306,6 +1315,178 @@ namespace eval Dwarf {
uplevel $body
}
+ # Emit a DWARF .debug_rnglists section.
+ #
+ # The target address size is based on the current target's address size.
+ #
+ # There is one mandatory positional argument, BODY, which must be Tcl code
+ # that emits the content of the section. It is evaluated in the caller's
+ # context.
+ #
+ # The following option can be used:
+ #
+ # - -is-64 true|false: Whether to use 64-bit DWARF instead of 32-bit DWARF.
+ # The default is 32-bit.
+
+ proc rnglists { args } {
+ variable _debug_rnglists_addr_size
+ variable _debug_rnglists_offset_size
+ variable _debug_rnglists_is_64_dwarf
+
+ parse_args {{"is-64" "false"}}
+
+ if { [llength $args] != 1 } {
+ error "rnglists proc expects one positional argument (body)"
+ }
+
+ lassign $args body
+
+ if [is_64_target] {
+ set _debug_rnglists_addr_size 8
+ } else {
+ set _debug_rnglists_addr_size 4
+ }
+
+ if { ${is-64} } {
+ set _debug_rnglists_offset_size 8
+ set _debug_rnglists_is_64_dwarf true
+ } else {
+ set _debug_rnglists_offset_size 4
+ set _debug_rnglists_is_64_dwarf false
+ }
+
+ _section ".debug_rnglists"
+
+ # Count of tables in the section.
+ variable _debug_rnglists_table_count 0
+
+ # Compute the label name for list at index LIST_IDX, for the current
+ # table.
+
+ proc _compute_list_label { list_idx } {
+ variable _debug_rnglists_table_count
+
+ return ".Lrnglists_table_${_debug_rnglists_table_count}_list_${list_idx}"
+ }
+
+ # Generate one table (header + offset array + range lists).
+ #
+ # Accepts one positional argument, BODY. BODY may call the LIST_
+ # procedure to generate rnglists.
+ #
+ # The -post-header-label option can be used to define a label just after
+ # the header of the table. This is the label that a DW_AT_rnglists_base
+ # attribute will usually refer to.
+
+ proc table { args } {
+ variable _debug_rnglists_table_count
+ variable _debug_rnglists_addr_size
+ variable _debug_rnglists_offset_size
+ variable _debug_rnglists_is_64_dwarf
+
+ parse_args {{post-header-label ""}}
+
+ if { [llength $args] != 1 } {
+ error "table proc expects one positional argument (body)"
+ }
+
+ lassign $args body
+
+ # Generate one range list.
+ #
+ # BODY may call the various procs defined below to generate list entries.
+ # They correspond to the range list entry kinds described in section 2.17.3
+ # of the DWARF 5 spec.
+ #
+ # To define a label pointing to the beginning of the list, use
+ # the conventional way of declaring and defining labels:
+ #
+ # declare_labels the_list
+ #
+ # the_list: list_ {
+ # ...
+ # }
+
+ proc list_ { body } {
+ variable _debug_rnglists_list_count
+
+ # Define a label for this list. It is used to build the offset
+ # array later.
+ set list_label [_compute_list_label $_debug_rnglists_list_count]
+ define_label $list_label
+
+ # Emit a DW_RLE_start_end entry.
+
+ proc start_end { start end } {
+ variable _debug_rnglists_addr_size
+
+ _op .byte 0x06 "DW_RLE_start_end"
+ _op .${_debug_rnglists_addr_size}byte $start "start"
+ _op .${_debug_rnglists_addr_size}byte $end "end"
+ }
+
+ uplevel $body
+
+ # Emit end of list.
+ _op .byte 0x00 "DW_RLE_end_of_list"
+
+ incr _debug_rnglists_list_count
+ }
+
+ # Count of lists in the table.
+ variable _debug_rnglists_list_count 0
+
+ # Generate the lists ops first, because we need to know how many
+ # lists there are to generate the header and offset table.
+ set lists_ops [_defer_to_string {
+ uplevel $body
+ }]
+
+ set post_unit_len_label \
+ [_compute_label "rnglists_table_${_debug_rnglists_table_count}_post_unit_len"]
+ set post_header_label \
+ [_compute_label "rnglists_table_${_debug_rnglists_table_count}_post_header"]
+ set table_end_label \
+ [_compute_label "rnglists_table_${_debug_rnglists_table_count}_end"]
+
+ # Emit the table header.
+ if { $_debug_rnglists_is_64_dwarf } {
+ _op .4byte 0xffffffff "unit length 1/2"
+ _op .8byte "$table_end_label - $post_unit_len_label" "unit length 2/2"
+ } else {
+ _op .4byte "$table_end_label - $post_unit_len_label" "unit length"
+ }
+
+ define_label $post_unit_len_label
+
+ _op .2byte 5 "dwarf version"
+ _op .byte $_debug_rnglists_addr_size "address size"
+ _op .byte 0 "segment selector size"
+ _op .4byte "$_debug_rnglists_list_count" "offset entry count"
+
+ define_label $post_header_label
+
+ # Define the user post-header label, if provided.
+ if { ${post-header-label} != "" } {
+ define_label ${post-header-label}
+ }
+
+ # Emit the offset array.
+ for {set list_idx 0} {$list_idx < $_debug_rnglists_list_count} {incr list_idx} {
+ set list_label [_compute_list_label $list_idx]
+ _op .${_debug_rnglists_offset_size}byte "$list_label - $post_header_label" "offset of list $list_idx"
+ }
+
+ # Emit the actual list data.
+ _emit "$lists_ops"
+
+ define_label $table_end_label
+
+ incr _debug_rnglists_table_count
+ }
+
+ uplevel $body
+ }
# Emit a DWARF .debug_line unit.
# OPTIONS is a list with an even number of elements containing
diff --git a/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp b/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp
new file mode 100644
index 0000000..e09cd4e
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp
@@ -0,0 +1,102 @@
+# Copyright 2020 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/>.
+
+# Test to reproduce the crash described in PR 26813.
+#
+# When reading a list in any table in the .debug_rnglists section, GDB would
+# read the header at offset 0 in the section (the header of the first table).
+# When the index of the list we read was greater than the number of lists of
+# the first table, GDB would erroneously report that the index is invalid.
+#
+# So this test creates a .debug_rnglists section with two tables. The second
+# table has more lists than the first one and we try to read a high index in
+# the second table.
+
+load_lib dwarf.exp
+
+if {![dwarf2_support]} {
+ return 0
+}
+
+# Test with 32-bit and 64-bit DWARF.
+foreach_with_prefix is_64 {false true} {
+ if { $is_64 } {
+ standard_testfile main.c -dw64.S
+ set testfile ${testfile}-dw64
+ } else {
+ standard_testfile main.c -dw32.S
+ set testfile ${testfile}-dw32
+ }
+
+ set asm_file [standard_output_file $srcfile2]
+ Dwarf::assemble $asm_file {
+ global is_64
+
+ # The CU uses the DW_FORM_rnglistx form to refer to the .debug_rnglists
+ # section.
+ cu {
+ version 5
+ is_64 $is_64
+ } {
+ DW_TAG_compile_unit {
+ {DW_AT_ranges 1 DW_FORM_rnglistx}
+ {DW_AT_rnglists_base cu_table DW_FORM_sec_offset}
+ } {
+ # This tests a DW_AT_ranges attribute of form DW_FORM_rnglistx on a
+ # function, which was buggy at some point.
+ DW_TAG_subprogram {
+ {DW_AT_name "foo"}
+ {DW_AT_ranges 2 DW_FORM_rnglistx}
+ }
+ }
+ }
+
+ rnglists -is-64 $is_64 {
+ # This table is unused, but exists so that the used table is not at
+ # the beginning of the section.
+ table {
+ list_ {
+ start_end 0x1000 0x2000
+ }
+ }
+
+ # The lists in this table are accessed by index (DW_FORM_rnglistx).
+ table -post-header-label cu_table {
+ # This list is unused, but exists to offset the next ones.
+ list_ {
+ start_end 0x2000 0x3000
+ }
+
+ # For the CU.
+ list_ {
+ start_end 0x3000 0x4000
+ }
+
+ # For function foo.
+ list_ {
+ start_end 0x3000 0x3010
+ }
+ }
+ }
+ }
+
+ if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+ }
+
+ # Sanity checks to make sure GDB slurped the symbols correctly.
+ gdb_test "p/x &foo" " = 0x3000"
+}
diff --git a/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp b/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp
new file mode 100644
index 0000000..d898d11
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp
@@ -0,0 +1,80 @@
+# Copyright 2020 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/>.
+
+# Test DW_AT_ranges attributes referencing the .debug_rnglists section using the
+# DW_FORM_sec_offset form.
+
+load_lib dwarf.exp
+
+if {![dwarf2_support]} {
+ return 0
+}
+
+foreach_with_prefix is_64 {false true} {
+ if { $is_64 } {
+ standard_testfile main.c -dw64.S
+ set testfile ${testfile}-dw64
+ } else {
+ standard_testfile main.c -dw32.S
+ set testfile ${testfile}-dw32
+ }
+
+ set asm_file [standard_output_file $srcfile2]
+ Dwarf::assemble $asm_file {
+ global is_64
+
+ declare_labels cu_range_list foo_range_list
+
+ # This CU uses the DW_FORM_sec_offset form to refer to the .debug_rnglists
+ # section.
+ cu {
+ version 5
+ is_64 $is_64
+ } {
+ DW_TAG_compile_unit {
+ {DW_AT_ranges $cu_range_list DW_FORM_sec_offset}
+ } {
+ DW_TAG_subprogram {
+ {DW_AT_name "foo"}
+ {DW_AT_ranges $foo_range_list DW_FORM_sec_offset}
+ }
+ }
+ }
+
+ rnglists -is-64 $is_64 {
+ # The lists in this table are accessed by direct offset
+ # (DW_FORM_sec_offset).
+ table {
+ # For the CU.
+ cu_range_list: list_ {
+ start_end 0x4000 0x5000
+ }
+
+ # For function foo.
+ foo_range_list: list_ {
+ start_end 0x4000 0x4010
+ }
+ }
+ }
+ }
+
+ if { [prepare_for_testing "failed to prepare" ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+ }
+
+ # Sanity checks to make sure GDB slurped the symbols correctly.
+ gdb_test "p/x &foo" " = 0x4000"
+}
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-25 18:53 ` Bernd Edlinger
2021-01-25 19:20 ` Bernd Edlinger
@ 2021-01-26 1:52 ` Simon Marchi via Gdb-patches
2021-01-26 7:47 ` Bernd Edlinger
1 sibling, 1 reply; 12+ messages in thread
From: Simon Marchi via Gdb-patches @ 2021-01-26 1:52 UTC (permalink / raw)
To: Bernd Edlinger, Tom de Vries, gdb-patches; +Cc: Tom Tromey
On 2021-01-25 1:53 p.m., Bernd Edlinger wrote:
> On 1/25/21 7:12 PM, Simon Marchi wrote:
>>
>>
>> On 2021-01-25 12:42 p.m., Bernd Edlinger wrote:
>>> On 1/25/21 5:36 PM, Simon Marchi wrote:
>>>>> Yes, unfortunately I have not any experience with writing such assembly
>>>>> tests, but I am always impressed when one of you does it though :-)
>>>>>
>>>>> Nevertheless, the test case seems to be stable from gcc-4.8 .. gcc-11,
>>>>> that it fails without the patch and passes with the patch.
>>>>>
>>>>> So is it okay to push my partial symbols test as-is?
>>>>
>>>> My patch here adds a test that uses DW_FORM_sec_offset to point
>>>> to a .debug_rnglists (DWARF5) section. Maybe that's sufficient,
>>>> but if not I could probably do a DWARF4 equivalent.
>>>>
>>>> https://sourceware.org/pipermail/gdb-patches/2021-January/175229.html
>>>>
>>>
>>> Yeah, the hardest part on a one-line change like this is always the test case.
>>>
>>> So, I tried this patch on current trunk, but it fails:
>>>
>>> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp ...
>>> ERROR: Couldn't load rnglists-multiple-cus-dw32 into GDB (GDB internal error).
>>> ERROR: Couldn't load rnglists-multiple-cus-dw64 into GDB (GDB internal error).
>>> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp ...
>>> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=false: p/x &foo
>>> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=true: p/x &foo
>>>
>>> This probably means that your test tests more than this single-line change alone?
>>
>> Hmm, with current master (so with Tom's patch merged),
>> gdb.dwarf2/rnglists-sec-offset.exp passes for me.
>>
>
> That will probably need investigation.
> Let's first check if I applied the corrrect test case,
> see attached patch.txt.
It looks like the right patch (I looked at your second patch.txt).
>
> tried to do "readelf --debug-dump rnglists-sec-offset-dw32" and
> "readelf --debug-dump rnglists-sec-offset-dw64"
>
> I used GNU readelf (GNU Binutils) 2.35.1
>
> I see a warning:
> readelf: Warnung: The .debug_rnglists section contains unsupported offset entry count: 2.
>
>
> what does that mean?
> Doesn't that indicate that the debug-info somehow wrong?
I think it's more that readelf is not yet able to read .debug_rnglists
sections with an array of offsets (used when you want to use the
DW_FORM_rnglistx form), probably because gcc does not use produce / use
it.
llvm-dwarfdump can dump it:
$ llvm-dwarfdump --debug-rnglists testsuite/outputs/gdb.dwarf2/rnglists-sec-offset/rnglists-sec-offset-dw32
testsuite/outputs/gdb.dwarf2/rnglists-sec-offset/rnglists-sec-offset-dw32: file format elf64-x86-64
.debug_rnglists contents:
range list header: length = 0x00000034, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000002
offsets: [
0x00000008
0x0000001a
]
ranges:
[0x0000000000004000, 0x0000000000005000)
<End of list>
[0x0000000000004000, 0x0000000000004010)
<End of list>
Notice "offset_entry_count = 0x00000002" and the two offsets in the
array of offsets.
> It happens pretty reliably when you have a function that contains an error
> handling that looks obvously "unlinkely" to the compiler, because it is guarded
> by an if-condition and calls abort(), while there are also code paths that
> don't call about. The parts that call abort are then in a separate cold section.
Indeed. I think it's good to have some tests with optimized code (in
addition to those that use the DWARF assembler), but we can't be too
specific about what we expect the generated code to look like. For
example, whether a given function is inlined or whether a function is
split in two. But at least, we can check that we can put a breakpoint
on the function and run there, that is always supposed to work. And
perhaps a new crazy optimization in GCC version n + 1 will make that
simple use case break, so that will notify us that need to support
something we don't support currently.
Simon
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE
2021-01-26 1:52 ` Simon Marchi via Gdb-patches
@ 2021-01-26 7:47 ` Bernd Edlinger
0 siblings, 0 replies; 12+ messages in thread
From: Bernd Edlinger @ 2021-01-26 7:47 UTC (permalink / raw)
To: Simon Marchi, Tom de Vries, gdb-patches; +Cc: Tom Tromey
On 1/26/21 2:52 AM, Simon Marchi wrote:
> On 2021-01-25 1:53 p.m., Bernd Edlinger wrote:
>> On 1/25/21 7:12 PM, Simon Marchi wrote:
>>>
>>>
>>> On 2021-01-25 12:42 p.m., Bernd Edlinger wrote:
>>>> On 1/25/21 5:36 PM, Simon Marchi wrote:
>>>>>> Yes, unfortunately I have not any experience with writing such assembly
>>>>>> tests, but I am always impressed when one of you does it though :-)
>>>>>>
>>>>>> Nevertheless, the test case seems to be stable from gcc-4.8 .. gcc-11,
>>>>>> that it fails without the patch and passes with the patch.
>>>>>>
>>>>>> So is it okay to push my partial symbols test as-is?
>>>>>
>>>>> My patch here adds a test that uses DW_FORM_sec_offset to point
>>>>> to a .debug_rnglists (DWARF5) section. Maybe that's sufficient,
>>>>> but if not I could probably do a DWARF4 equivalent.
>>>>>
>>>>> https://sourceware.org/pipermail/gdb-patches/2021-January/175229.html
>>>>>
>>>>
>>>> Yeah, the hardest part on a one-line change like this is always the test case.
>>>>
>>>> So, I tried this patch on current trunk, but it fails:
>>>>
>>>> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-multiple-cus.exp ...
>>>> ERROR: Couldn't load rnglists-multiple-cus-dw32 into GDB (GDB internal error).
>>>> ERROR: Couldn't load rnglists-multiple-cus-dw64 into GDB (GDB internal error).
>>>> Running /home/ed/gnu/gdb-build-1/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.dwarf2/rnglists-sec-offset.exp ...
>>>> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=false: p/x &foo
>>>> FAIL: gdb.dwarf2/rnglists-sec-offset.exp: is_64=true: p/x &foo
>>>>
>>>> This probably means that your test tests more than this single-line change alone?
>>>
>>> Hmm, with current master (so with Tom's patch merged),
>>> gdb.dwarf2/rnglists-sec-offset.exp passes for me.
>>>
>>
>> That will probably need investigation.
>> Let's first check if I applied the corrrect test case,
>> see attached patch.txt.
>
> It looks like the right patch (I looked at your second patch.txt).
>
Ah, sorry, my fault.
I have done the test with the wrong version,
now the test passes for me as well.
Bernd.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2021-01-26 7:47 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-25 12:24 [PATCH][gdb/symtab] Handle DW_AT_ranges with DW_FORM_sec_off in partial DIE Tom de Vries
2021-01-25 12:52 ` Bernd Edlinger
2021-01-25 15:27 ` Simon Marchi via Gdb-patches
2021-01-25 15:37 ` Tom de Vries
2021-01-25 15:47 ` Bernd Edlinger
2021-01-25 16:36 ` Simon Marchi via Gdb-patches
2021-01-25 17:42 ` Bernd Edlinger
2021-01-25 18:12 ` Simon Marchi via Gdb-patches
2021-01-25 18:53 ` Bernd Edlinger
2021-01-25 19:20 ` Bernd Edlinger
2021-01-26 1:52 ` Simon Marchi via Gdb-patches
2021-01-26 7:47 ` Bernd Edlinger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox