* [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