public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
@ 2021-07-29 21:23 Tom de Vries
  2021-07-30  1:25 ` Simon Marchi
  0 siblings, 1 reply; 8+ messages in thread
From: Tom de Vries @ 2021-07-29 21:23 UTC (permalink / raw)
  To: gdb-patches

Hi,

In PR28004 the following warning / Internal error is reported:
...
$ gdb -q -batch \
    -iex "set sysroot $(pwd -P)/repro" \
    ./repro/gdb \
    ./repro/core \
    -ex bt
  ...
 Program terminated with signal SIGABRT, Aborted.
 #0  0x00007ff8fe8e5d22 in raise () from repro/usr/lib/libc.so.6
 [Current thread is 1 (LWP 1762498)]
 #1  0x00007ff8fe8cf862 in abort () from repro/usr/lib/libc.so.6
 warning: (Internal error: pc 0x7ff8feb2c21d in read in psymtab, \
           but not in symtab.)
 warning: (Internal error: pc 0x7ff8feb2c218 in read in psymtab, \
           but not in symtab.)
  ...
 #2  0x00007ff8feb2c21e in __gnu_debug::_Error_formatter::_M_error() const \
   [clone .cold] (warning: (Internal error: pc 0x7ff8feb2c21d in read in \
   psymtab, but not in symtab.)

) from repro/usr/lib/libstdc++.so.6
...

The warning is about the following:
- in find_pc_sect_compunit_symtab we try to find the addres
  (0x7ff8feb2c218 / 0x7ff8feb2c21d) in the symtabs.
- that fails, so we try again in the partial symtabs.
- we find a matching partial symtab
- however, the partial symtab has a matching symtab, so
  we should have found a matching symtab in the first step.

The addresses are:
...
(gdb) info sym 0x7ff8feb2c218
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] in \
  section .text of repro/usr/lib/libstdc++.so.6
(gdb) info sym 0x7ff8feb2c21d
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] + 5 in \
  section .text of repro/usr/lib/libstdc++.so.6
...
which correspond to unrelocated addresses 0x9c218 and 0x9c21d:
...
$ nm -C  repro/usr/lib/libstdc++.so.6.0.29 | grep 000000000009c218
000000000009c218 t __gnu_debug::_Error_formatter::_M_error() const \
  [clone .cold]
...

The unrelocated addresses can be found in the partial symbols addresss map:
...
(gdb) set $map = (addrmap_fixed *)m_partial_symtabs->psymtabs_addrmap
(gdb) p /x $map->transitions[24]
$47 = {addr = 0x9989c, value = 0x231d1b0}
(gdb) p /x $map->transitions[25]
$48 = {addr = 0xa2170, value = 0x5439980}
...
and indeed we do:
...
(gdb) p ps
$1 = (partial_symtab *) 0x231d1b0
...
but not in the symbols address map:
...
(gdb) set $symtab = ps->get_compunit_symtab (objfile)
(gdb) set $map = (addrmap_fixed *)$symtab.blockvector.map
(gdb) p /x $map.transitions[20]
$42 = {addr = 0x7ff8feb2993a, value = 0x0}
(gdb) p /x $map.transitions[21]
$43 = {addr = 0x7ff8feb322b0, value = 0x6155ef0}
...

The reason for the difference is between the two address maps (who are based on
the same data), is this code in dwarf2_rnglists_process:
...
      /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
      if (range_beginning + baseaddr == 0
          && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_rnglists entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
          continue;
        }
...
which triggers for the partial symbol table case (with unrelocated addresses),
but not for the symbol table case (with relocated addresses).

The difference is that in the latter case, baseaddr (initialized from
objfile->text_section_offset ()) isn't 0.

Fix this by removing the baseaddr part from the condition.  Same for
dwarf2_ranges_process.

The test-case excercises the latter only for now.

Tested on x86_64-linux.

Any comments?

Thanks,
- Tom

[gdb/symtab] Fix zero address complaint for shlib

gdb/ChangeLog:

2021-07-29  Tom de Vries  <tdevries@suse.de>

	PR symtab/28004
	* gdb/dwarf2/read.c (dwarf2_rnglists_process, dwarf2_ranges_process):
	Fix zero address complaint.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp: New file.

---
 gdb/dwarf2/read.c                               | 10 +--
 gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c | 21 ++++++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.c       | 24 ++++++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp     | 97 +++++++++++++++++++++++++
 4 files changed, 144 insertions(+), 8 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 6f1b453ef45..de84c47b626 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -13631,7 +13631,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   /* Base address selection entry.  */
   gdb::optional<CORE_ADDR> base;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
   bool overflow = false;
   ULONGEST addr_index;
   struct dwarf2_section_info *rnglists_section;
@@ -13648,8 +13647,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
     }
   buffer = rnglists_section->buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       /* Initialize it due to a false compiler warning.  */
@@ -13791,7 +13788,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_rnglists entry has start address of zero"
@@ -13833,7 +13830,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
   gdb::optional<CORE_ADDR> base;
   unsigned int dummy;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
 
   if (cu_header->version >= 5)
     return dwarf2_rnglists_process (offset, cu, tag, callback);
@@ -13849,8 +13845,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
     }
   buffer = per_objfile->per_bfd->ranges.buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       CORE_ADDR range_beginning, range_end;
@@ -13901,7 +13895,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_ranges entry has start address of zero"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
new file mode 100644
index 00000000000..1ddc8d6677b
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
@@ -0,0 +1,21 @@
+/*
+   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/>.  */
+
+void
+foo (void)
+{
+  asm ("foo_label: .globl foo_label");
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
new file mode 100644
index 00000000000..8d705cac44a
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
@@ -0,0 +1,24 @@
+/*
+   Copyright 2015-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/>.  */
+
+extern void foo (void);
+
+void
+main (void)
+{
+  asm ("main_label: .globl main_label");
+  foo ();
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
new file mode 100644
index 00000000000..1805733db6c
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
@@ -0,0 +1,97 @@
+# Copyright 2015-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/>.
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    verbose "Skipping $gdb_test_file_name."
+    return 0
+}
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# The .c files use __attribute__.
+if [get_compiler_info] {
+    return -1
+}
+if !$gcc_compiled {
+    verbose "Skipping $gdb_test_file_name."
+    return 0
+}
+
+standard_testfile .c -shlib.c -dw.S
+
+set asm_file [standard_output_file $srcfile3]
+Dwarf::assemble $asm_file {
+    global srcdir subdir srcfile2
+    declare_labels ranges_label
+
+    cu {} {
+	compile_unit {
+	    {language @DW_LANG_C}
+	    {name $srcfile2}
+	    {ranges ${ranges_label} DW_FORM_sec_offset}
+	} {
+	    subprogram {
+		{external 1 flag}
+		{name foo}
+	    }
+	}
+    }
+
+    ranges {is_64 [is_64_target]} {
+	ranges_label: sequence {
+	    base 0
+	    range 0 1
+	}
+    }
+}
+
+set lib1 [standard_output_file shr1.sl]
+set lib_opts "nodebug"
+
+set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
+if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
+    untested "failed to compile"
+    return -1
+}
+
+set exec_opts [list debug shlib=${lib1}]
+set sources ${srcdir}/${subdir}/${srcfile}
+if { [gdb_compile $sources  ${binfile} executable \
+	  $exec_opts] != ""} {
+    untested "failed to compile"
+    return -1
+}
+
+clean_restart $binfile
+
+# Don't load the symbols for $lib1 during runto_main.
+# Instead, we do this afterwards using "sharedlibrary $lib1".
+gdb_test_no_output "set auto-solib-add off"
+
+if ![runto_main] {
+    return -1
+}
+
+# Test for presence of complaint.
+set complaint_re ".debug_ranges entry has start address of zero"
+set re \
+    "During symbol reading: $complaint_re \\\[in module \[^\r\n\]*\\\]"
+with_complaints 1 {
+    gdb_test "sharedlibrary $lib1" $re "Zero address complaint"
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
  2021-07-29 21:23 [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib Tom de Vries
@ 2021-07-30  1:25 ` Simon Marchi
  2021-07-30  1:48   ` Simon Marchi
  2021-07-30 15:25   ` Tom de Vries
  0 siblings, 2 replies; 8+ messages in thread
From: Simon Marchi @ 2021-07-30  1:25 UTC (permalink / raw)
  To: Tom de Vries, gdb-patches

On 2021-07-29 5:23 p.m., Tom de Vries wrote:
> Hi,
> 
> In PR28004 the following warning / Internal error is reported:
> ...
> $ gdb -q -batch \
>     -iex "set sysroot $(pwd -P)/repro" \
>     ./repro/gdb \
>     ./repro/core \
>     -ex bt
>   ...
>  Program terminated with signal SIGABRT, Aborted.
>  #0  0x00007ff8fe8e5d22 in raise () from repro/usr/lib/libc.so.6
>  [Current thread is 1 (LWP 1762498)]
>  #1  0x00007ff8fe8cf862 in abort () from repro/usr/lib/libc.so.6
>  warning: (Internal error: pc 0x7ff8feb2c21d in read in psymtab, \
>            but not in symtab.)
>  warning: (Internal error: pc 0x7ff8feb2c218 in read in psymtab, \
>            but not in symtab.)
>   ...
>  #2  0x00007ff8feb2c21e in __gnu_debug::_Error_formatter::_M_error() const \
>    [clone .cold] (warning: (Internal error: pc 0x7ff8feb2c21d in read in \
>    psymtab, but not in symtab.)
> 
> ) from repro/usr/lib/libstdc++.so.6
> ...
> 
> The warning is about the following:
> - in find_pc_sect_compunit_symtab we try to find the addres

addres -> address

>   (0x7ff8feb2c218 / 0x7ff8feb2c21d) in the symtabs.
> - that fails, so we try again in the partial symtabs.
> - we find a matching partial symtab
> - however, the partial symtab has a matching symtab, so
>   we should have found a matching symtab in the first step.
> 
> The addresses are:
> ...
> (gdb) info sym 0x7ff8feb2c218
> __gnu_debug::_Error_formatter::_M_error() const [clone .cold] in \
>   section .text of repro/usr/lib/libstdc++.so.6
> (gdb) info sym 0x7ff8feb2c21d
> __gnu_debug::_Error_formatter::_M_error() const [clone .cold] + 5 in \
>   section .text of repro/usr/lib/libstdc++.so.6
> ...
> which correspond to unrelocated addresses 0x9c218 and 0x9c21d:
> ...
> $ nm -C  repro/usr/lib/libstdc++.so.6.0.29 | grep 000000000009c218
> 000000000009c218 t __gnu_debug::_Error_formatter::_M_error() const \
>   [clone .cold]
> ...
> 
> The unrelocated addresses can be found in the partial symbols addresss map:
> ...
> (gdb) set $map = (addrmap_fixed *)m_partial_symtabs->psymtabs_addrmap
> (gdb) p /x $map->transitions[24]
> $47 = {addr = 0x9989c, value = 0x231d1b0}
> (gdb) p /x $map->transitions[25]
> $48 = {addr = 0xa2170, value = 0x5439980}
> ...
> and indeed we do:
> ...
> (gdb) p ps
> $1 = (partial_symtab *) 0x231d1b0
> ...
> but not in the symbols address map:
> ...
> (gdb) set $symtab = ps->get_compunit_symtab (objfile)
> (gdb) set $map = (addrmap_fixed *)$symtab.blockvector.map
> (gdb) p /x $map.transitions[20]
> $42 = {addr = 0x7ff8feb2993a, value = 0x0}
> (gdb) p /x $map.transitions[21]
> $43 = {addr = 0x7ff8feb322b0, value = 0x6155ef0}
> ...
> 
> The reason for the difference is between the two address maps (who are based on
> the same data), is this code in dwarf2_rnglists_process:
> ...
>       /* A not-uncommon case of bad debug info.
>          Don't pollute the addrmap with bad data.  */
>       if (range_beginning + baseaddr == 0
>           && !per_objfile->per_bfd->has_section_at_zero)
>         {
>           complaint (_(".debug_rnglists entry has start address of zero"
>                        " [in module %s]"), objfile_name (objfile));
>           continue;
>         }
> ...
> which triggers for the partial symbol table case (with unrelocated addresses),
> but not for the symbol table case (with relocated addresses).

Interesting.  Before Tom Tromey's changes to make partial symtabs
shareable between objfiles, partial symbols were also relocated right?
So it would mean that the `range_beginning + baseaddr == 0` was wrong
for both the partial and full symtabs, but with that change it became
right for the partial symtabs?

> 
> The difference is that in the latter case, baseaddr (initialized from
> objfile->text_section_offset ()) isn't 0.
> 
> Fix this by removing the baseaddr part from the condition.  Same for
> dwarf2_ranges_process.

The change looks good to me.  I am still confused by these weird ranges
starting at zero, but given that the check is already present, let's
make it right.

> The test-case excercises the latter only for now.
> 
> Tested on x86_64-linux.
> 
> Any comments?

Maybe state in the commit message what impact this patch has.  It gets
rid of the warning shown above?

> diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
> new file mode 100644
> index 00000000000..1805733db6c
> --- /dev/null
> +++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
> @@ -0,0 +1,97 @@
> +# Copyright 2015-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/>.
> +load_lib dwarf.exp

Can you please add a short comment explaining what this test intends to
test?

> +
> +# This test can only be run on targets which support DWARF-2 and use gas.
> +if {![dwarf2_support]} {
> +    verbose "Skipping $gdb_test_file_name."
> +    return 0
> +}
> +
> +if {[skip_shlib_tests]} {
> +    return 0
> +}
> +
> +# The .c files use __attribute__.
> +if [get_compiler_info] {
> +    return -1
> +}
> +if !$gcc_compiled {
> +    verbose "Skipping $gdb_test_file_name."
> +    return 0
> +}
> +
> +standard_testfile .c -shlib.c -dw.S
> +
> +set asm_file [standard_output_file $srcfile3]
> +Dwarf::assemble $asm_file {
> +    global srcdir subdir srcfile2
> +    declare_labels ranges_label
> +
> +    cu {} {
> +	compile_unit {
> +	    {language @DW_LANG_C}
> +	    {name $srcfile2}
> +	    {ranges ${ranges_label} DW_FORM_sec_offset}
> +	} {
> +	    subprogram {
> +		{external 1 flag}
> +		{name foo}
> +	    }
> +	}
> +    }
> +
> +    ranges {is_64 [is_64_target]} {
> +	ranges_label: sequence {
> +	    base 0
> +	    range 0 1
> +	}
> +    }
> +}
> +
> +set lib1 [standard_output_file shr1.sl]
> +set lib_opts "nodebug"
> +
> +set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
> +if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
> +    untested "failed to compile"
> +    return -1
> +}
> +
> +set exec_opts [list debug shlib=${lib1}]
> +set sources ${srcdir}/${subdir}/${srcfile}
> +if { [gdb_compile $sources  ${binfile} executable \
> +	  $exec_opts] != ""} {
> +    untested "failed to compile"
> +    return -1
> +}
> +
> +clean_restart $binfile
> +
> +# Don't load the symbols for $lib1 during runto_main.
> +# Instead, we do this afterwards using "sharedlibrary $lib1".
> +gdb_test_no_output "set auto-solib-add off"
> +
> +if ![runto_main] {
> +    return -1
> +}

I think runto_main does not (yet) produce a FAIL on failure, hence why
we need `fail "could not run to main"` everywhere.

Simon

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
  2021-07-30  1:25 ` Simon Marchi
@ 2021-07-30  1:48   ` Simon Marchi
  2021-07-30 15:25   ` Tom de Vries
  1 sibling, 0 replies; 8+ messages in thread
From: Simon Marchi @ 2021-07-30  1:48 UTC (permalink / raw)
  To: Tom de Vries, gdb-patches

>> The test-case excercises the latter only for now.
>>
>> Tested on x86_64-linux.
>>
>> Any comments?
> 
> Maybe state in the commit message what impact this patch has.  It gets
> rid of the warning shown above?

I think I was wrong here: we do check that the warning is printed while
reading partial symbols?  Or while reading full symbols?  I'm confused
here.

In any case, here's an addendum to your patch in case you'd like to add
coverage for .debug_rnglists:


From 096253d5f663b035f144e472d47642a4a511f87c Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@polymtl.ca>
Date: Thu, 29 Jul 2021 21:42:10 -0400
Subject: [PATCH] Add .debug_rnglists to test

Change-Id: I724166d8736d0a855ae39568b61c39b3b7aa6b33
---
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp | 132 +++++++++++++-------
 1 file changed, 85 insertions(+), 47 deletions(-)

diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
index 1805733db6cf..7916182699ba 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
@@ -35,63 +35,101 @@ if !$gcc_compiled {
 
 standard_testfile .c -shlib.c -dw.S
 
-set asm_file [standard_output_file $srcfile3]
-Dwarf::assemble $asm_file {
-    global srcdir subdir srcfile2
-    declare_labels ranges_label
-
-    cu {} {
-	compile_unit {
-	    {language @DW_LANG_C}
-	    {name $srcfile2}
-	    {ranges ${ranges_label} DW_FORM_sec_offset}
-	} {
-	    subprogram {
-		{external 1 flag}
-		{name foo}
+# Test with both a .debug_ranges section (DWARF 4) and a .debug_rnglists
+# section (DWARF 5).
+
+foreach_with_prefix ranges_sect {ranges rnglists} {
+    set asm_file [standard_output_file ${ranges_sect}-$srcfile3]
+
+    if { $ranges_sect == "ranges" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels ranges_label
+
+	    cu {} {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${ranges_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
+
+	    ranges {is_64 [is_64_target]} {
+		ranges_label: sequence {
+		    base 0
+		    range 0 1
+		}
 	    }
 	}
-    }
+    } elseif { $ranges_sect == "rnglists" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels rnglists_label
+
+	    cu {
+		version 5
+	    } {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${rnglists_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
 
-    ranges {is_64 [is_64_target]} {
-	ranges_label: sequence {
-	    base 0
-	    range 0 1
+	    rnglists {
+		table {
+		    rnglists_label: list_ {
+			start_end 0 1
+		    }
+		}
+	    }
 	}
+    } else {
+	error "invalid ranges section kind"
     }
-}
 
-set lib1 [standard_output_file shr1.sl]
-set lib_opts "nodebug"
+    set lib1 [standard_output_file shr1.sl]
+    set lib_opts "nodebug"
 
-set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
-if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
-    untested "failed to compile"
-    return -1
-}
+    set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
+    if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
+	untested "failed to compile"
+	return -1
+    }
 
-set exec_opts [list debug shlib=${lib1}]
-set sources ${srcdir}/${subdir}/${srcfile}
-if { [gdb_compile $sources  ${binfile} executable \
-	  $exec_opts] != ""} {
-    untested "failed to compile"
-    return -1
-}
+    set exec_opts [list debug shlib=${lib1}]
+    set sources ${srcdir}/${subdir}/${srcfile}
+    if { [gdb_compile $sources  ${binfile} executable \
+	      $exec_opts] != ""} {
+	untested "failed to compile"
+	return -1
+    }
 
-clean_restart $binfile
+    clean_restart $binfile
 
-# Don't load the symbols for $lib1 during runto_main.
-# Instead, we do this afterwards using "sharedlibrary $lib1".
-gdb_test_no_output "set auto-solib-add off"
+    # Don't load the symbols for $lib1 during runto_main.
+    # Instead, we do this afterwards using "sharedlibrary $lib1".
+    gdb_test_no_output "set auto-solib-add off"
 
-if ![runto_main] {
-    return -1
-}
+    if ![runto_main] {
+	return -1
+    }
 
-# Test for presence of complaint.
-set complaint_re ".debug_ranges entry has start address of zero"
-set re \
-    "During symbol reading: $complaint_re \\\[in module \[^\r\n\]*\\\]"
-with_complaints 1 {
-    gdb_test "sharedlibrary $lib1" $re "Zero address complaint"
+    # Test for presence of complaint.
+    set complaint_re ".debug_${ranges_sect} entry has start address of zero"
+    set re \
+	"During symbol reading: $complaint_re \\\[in module \[^\r\n\]*\\\]"
+    with_complaints 1 {
+	gdb_test "sharedlibrary $lib1" $re "Zero address complaint"
+    }
 }
-- 
2.32.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
  2021-07-30  1:25 ` Simon Marchi
  2021-07-30  1:48   ` Simon Marchi
@ 2021-07-30 15:25   ` Tom de Vries
  2021-07-30 17:50     ` Simon Marchi
  1 sibling, 1 reply; 8+ messages in thread
From: Tom de Vries @ 2021-07-30 15:25 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 7913 bytes --]

On 7/30/21 3:25 AM, Simon Marchi wrote:
> On 2021-07-29 5:23 p.m., Tom de Vries wrote:
>> Hi,
>>
>> In PR28004 the following warning / Internal error is reported:
>> ...
>> $ gdb -q -batch \
>>     -iex "set sysroot $(pwd -P)/repro" \
>>     ./repro/gdb \
>>     ./repro/core \
>>     -ex bt
>>   ...
>>  Program terminated with signal SIGABRT, Aborted.
>>  #0  0x00007ff8fe8e5d22 in raise () from repro/usr/lib/libc.so.6
>>  [Current thread is 1 (LWP 1762498)]
>>  #1  0x00007ff8fe8cf862 in abort () from repro/usr/lib/libc.so.6
>>  warning: (Internal error: pc 0x7ff8feb2c21d in read in psymtab, \
>>            but not in symtab.)
>>  warning: (Internal error: pc 0x7ff8feb2c218 in read in psymtab, \
>>            but not in symtab.)
>>   ...
>>  #2  0x00007ff8feb2c21e in __gnu_debug::_Error_formatter::_M_error() const \
>>    [clone .cold] (warning: (Internal error: pc 0x7ff8feb2c21d in read in \
>>    psymtab, but not in symtab.)
>>
>> ) from repro/usr/lib/libstdc++.so.6
>> ...
>>
>> The warning is about the following:
>> - in find_pc_sect_compunit_symtab we try to find the addres
> 
> addres -> address
> 

Fixed.

>>   (0x7ff8feb2c218 / 0x7ff8feb2c21d) in the symtabs.
>> - that fails, so we try again in the partial symtabs.
>> - we find a matching partial symtab
>> - however, the partial symtab has a matching symtab, so
>>   we should have found a matching symtab in the first step.
>>
>> The addresses are:
>> ...
>> (gdb) info sym 0x7ff8feb2c218
>> __gnu_debug::_Error_formatter::_M_error() const [clone .cold] in \
>>   section .text of repro/usr/lib/libstdc++.so.6
>> (gdb) info sym 0x7ff8feb2c21d
>> __gnu_debug::_Error_formatter::_M_error() const [clone .cold] + 5 in \
>>   section .text of repro/usr/lib/libstdc++.so.6
>> ...
>> which correspond to unrelocated addresses 0x9c218 and 0x9c21d:
>> ...
>> $ nm -C  repro/usr/lib/libstdc++.so.6.0.29 | grep 000000000009c218
>> 000000000009c218 t __gnu_debug::_Error_formatter::_M_error() const \
>>   [clone .cold]
>> ...
>>
>> The unrelocated addresses can be found in the partial symbols addresss map:
>> ...
>> (gdb) set $map = (addrmap_fixed *)m_partial_symtabs->psymtabs_addrmap
>> (gdb) p /x $map->transitions[24]
>> $47 = {addr = 0x9989c, value = 0x231d1b0}
>> (gdb) p /x $map->transitions[25]
>> $48 = {addr = 0xa2170, value = 0x5439980}
>> ...
>> and indeed we do:
>> ...
>> (gdb) p ps
>> $1 = (partial_symtab *) 0x231d1b0
>> ...
>> but not in the symbols address map:
>> ...
>> (gdb) set $symtab = ps->get_compunit_symtab (objfile)
>> (gdb) set $map = (addrmap_fixed *)$symtab.blockvector.map
>> (gdb) p /x $map.transitions[20]
>> $42 = {addr = 0x7ff8feb2993a, value = 0x0}
>> (gdb) p /x $map.transitions[21]
>> $43 = {addr = 0x7ff8feb322b0, value = 0x6155ef0}
>> ...
>>
>> The reason for the difference is between the two address maps (who are based on
>> the same data), is this code in dwarf2_rnglists_process:
>> ...
>>       /* A not-uncommon case of bad debug info.
>>          Don't pollute the addrmap with bad data.  */
>>       if (range_beginning + baseaddr == 0
>>           && !per_objfile->per_bfd->has_section_at_zero)
>>         {
>>           complaint (_(".debug_rnglists entry has start address of zero"
>>                        " [in module %s]"), objfile_name (objfile));
>>           continue;
>>         }
>> ...
>> which triggers for the partial symbol table case (with unrelocated addresses),
>> but not for the symbol table case (with relocated addresses).
> 
> Interesting.  Before Tom Tromey's changes to make partial symtabs
> shareable between objfiles, partial symbols were also relocated right?
> So it would mean that the `range_beginning + baseaddr == 0` was wrong
> for both the partial and full symtabs, but with that change it became
> right for the partial symtabs?
> 

I build gdb 9.2 and did observe that the warning / Internal error does
not trigger there.  I have not yet checked this in more detail, but that
might be because of what you suggest here.

>>
>> The difference is that in the latter case, baseaddr (initialized from
>> objfile->text_section_offset ()) isn't 0.
>>
>> Fix this by removing the baseaddr part from the condition.  Same for
>> dwarf2_ranges_process.
> 
> The change looks good to me.  I am still confused by these weird ranges
> starting at zero, but given that the check is already present, let's
> make it right.
> 
>> The test-case excercises the latter only for now.
>>
>> Tested on x86_64-linux.
>>
>> Any comments?
> 
> Maybe state in the commit message what impact this patch has.  It gets
> rid of the warning shown above?
> 

Done.

>> diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
>> new file mode 100644
>> index 00000000000..1805733db6c
>> --- /dev/null
>> +++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
>> @@ -0,0 +1,97 @@
>> +# Copyright 2015-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/>.
>> +load_lib dwarf.exp
> 
> Can you please add a short comment explaining what this test intends to
> test?
> 

Done.

>> +
>> +# This test can only be run on targets which support DWARF-2 and use gas.
>> +if {![dwarf2_support]} {
>> +    verbose "Skipping $gdb_test_file_name."
>> +    return 0
>> +}
>> +
>> +if {[skip_shlib_tests]} {
>> +    return 0
>> +}
>> +
>> +# The .c files use __attribute__.
>> +if [get_compiler_info] {
>> +    return -1
>> +}
>> +if !$gcc_compiled {
>> +    verbose "Skipping $gdb_test_file_name."
>> +    return 0
>> +}
>> +
>> +standard_testfile .c -shlib.c -dw.S
>> +
>> +set asm_file [standard_output_file $srcfile3]
>> +Dwarf::assemble $asm_file {
>> +    global srcdir subdir srcfile2
>> +    declare_labels ranges_label
>> +
>> +    cu {} {
>> +	compile_unit {
>> +	    {language @DW_LANG_C}
>> +	    {name $srcfile2}
>> +	    {ranges ${ranges_label} DW_FORM_sec_offset}
>> +	} {
>> +	    subprogram {
>> +		{external 1 flag}
>> +		{name foo}
>> +	    }
>> +	}
>> +    }
>> +
>> +    ranges {is_64 [is_64_target]} {
>> +	ranges_label: sequence {
>> +	    base 0
>> +	    range 0 1
>> +	}
>> +    }
>> +}
>> +
>> +set lib1 [standard_output_file shr1.sl]
>> +set lib_opts "nodebug"
>> +
>> +set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
>> +if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
>> +    untested "failed to compile"
>> +    return -1
>> +}
>> +
>> +set exec_opts [list debug shlib=${lib1}]
>> +set sources ${srcdir}/${subdir}/${srcfile}
>> +if { [gdb_compile $sources  ${binfile} executable \
>> +	  $exec_opts] != ""} {
>> +    untested "failed to compile"
>> +    return -1
>> +}
>> +
>> +clean_restart $binfile
>> +
>> +# Don't load the symbols for $lib1 during runto_main.
>> +# Instead, we do this afterwards using "sharedlibrary $lib1".
>> +gdb_test_no_output "set auto-solib-add off"
>> +
>> +if ![runto_main] {
>> +    return -1
>> +}
> 
> I think runto_main does not (yet) produce a FAIL on failure, hence why
> we need `fail "could not run to main"` everywhere.

Done.

Thanks for the review, and the .debug_rnglists addition.

I've added the .debug_rnglists addition here as well, and added testing
the complaint when doing gdb_load $lib1, in other words, the unrelocated
case (which was already passing before this patch).

Thanks,
- Tom

[-- Attachment #2: 0001-gdb-symtab-Fix-zero-address-complaint-for-shlib.patch --]
[-- Type: text/x-patch, Size: 12452 bytes --]

[gdb/symtab] Fix zero address complaint for shlib

In PR28004 the following warning / Internal error is reported:
...
$ gdb -q -batch \
    -iex "set sysroot $(pwd -P)/repro" \
    ./repro/gdb \
    ./repro/core \
    -ex bt
  ...
 Program terminated with signal SIGABRT, Aborted.
 #0  0x00007ff8fe8e5d22 in raise () from repro/usr/lib/libc.so.6
 [Current thread is 1 (LWP 1762498)]
 #1  0x00007ff8fe8cf862 in abort () from repro/usr/lib/libc.so.6
 warning: (Internal error: pc 0x7ff8feb2c21d in read in psymtab, \
           but not in symtab.)
 warning: (Internal error: pc 0x7ff8feb2c218 in read in psymtab, \
           but not in symtab.)
  ...
 #2  0x00007ff8feb2c21e in __gnu_debug::_Error_formatter::_M_error() const \
   [clone .cold] (warning: (Internal error: pc 0x7ff8feb2c21d in read in \
   psymtab, but not in symtab.)

) from repro/usr/lib/libstdc++.so.6
...

The warning is about the following:
- in find_pc_sect_compunit_symtab we try to find the address
  (0x7ff8feb2c218 / 0x7ff8feb2c21d) in the symtabs.
- that fails, so we try again in the partial symtabs.
- we find a matching partial symtab
- however, the partial symtab has a matching symtab, so
  we should have found a matching symtab in the first step.

The addresses are:
...
(gdb) info sym 0x7ff8feb2c218
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] in \
  section .text of repro/usr/lib/libstdc++.so.6
(gdb) info sym 0x7ff8feb2c21d
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] + 5 in \
  section .text of repro/usr/lib/libstdc++.so.6
...
which correspond to unrelocated addresses 0x9c218 and 0x9c21d:
...
$ nm -C  repro/usr/lib/libstdc++.so.6.0.29 | grep 000000000009c218
000000000009c218 t __gnu_debug::_Error_formatter::_M_error() const \
  [clone .cold]
...

The unrelocated addresses can be found in the partial symbols addresss map:
...
(gdb) set $map = (addrmap_fixed *)m_partial_symtabs->psymtabs_addrmap
(gdb) p /x $map->transitions[24]
$47 = {addr = 0x9989c, value = 0x231d1b0}
(gdb) p /x $map->transitions[25]
$48 = {addr = 0xa2170, value = 0x5439980}
...
and indeed we do:
...
(gdb) p ps
$1 = (partial_symtab *) 0x231d1b0
...
but not in the symbols address map:
...
(gdb) set $symtab = ps->get_compunit_symtab (objfile)
(gdb) set $map = (addrmap_fixed *)$symtab.blockvector.map
(gdb) p /x $map.transitions[20]
$42 = {addr = 0x7ff8feb2993a, value = 0x0}
(gdb) p /x $map.transitions[21]
$43 = {addr = 0x7ff8feb322b0, value = 0x6155ef0}
...

The reason for the difference between the two address maps (who are based on
the same data), is this code in dwarf2_rnglists_process:
...
      /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
      if (range_beginning + baseaddr == 0
          && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_rnglists entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
          continue;
        }
...
which triggers for the partial symbol table case (with unrelocated addresses),
but not for the symbol table case (with relocated addresses).

The difference is that in the latter case, baseaddr (initialized from
objfile->text_section_offset ()) isn't 0.

Fix this by removing the baseaddr part from the condition.  Same for
dwarf2_ranges_process.

The effect is that:
- the complaint is triggered, and
- the warning / Internal error is no longer triggered.

Tested on x86_64-linux.

gdb/ChangeLog:

2021-07-29  Simon Marchi  <simon.marchi@polymtl.ca>
	    Tom de Vries  <tdevries@suse.de>

	PR symtab/28004
	* gdb/dwarf2/read.c (dwarf2_rnglists_process, dwarf2_ranges_process):
	Fix zero address complaint.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp: New file.

---
 gdb/dwarf2/read.c                               |  10 +-
 gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c |  21 ++++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.c       |  24 ++++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp     | 150 ++++++++++++++++++++++++
 4 files changed, 197 insertions(+), 8 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 6f1b453ef45..de84c47b626 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -13631,7 +13631,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   /* Base address selection entry.  */
   gdb::optional<CORE_ADDR> base;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
   bool overflow = false;
   ULONGEST addr_index;
   struct dwarf2_section_info *rnglists_section;
@@ -13648,8 +13647,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
     }
   buffer = rnglists_section->buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       /* Initialize it due to a false compiler warning.  */
@@ -13791,7 +13788,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_rnglists entry has start address of zero"
@@ -13833,7 +13830,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
   gdb::optional<CORE_ADDR> base;
   unsigned int dummy;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
 
   if (cu_header->version >= 5)
     return dwarf2_rnglists_process (offset, cu, tag, callback);
@@ -13849,8 +13845,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
     }
   buffer = per_objfile->per_bfd->ranges.buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       CORE_ADDR range_beginning, range_end;
@@ -13901,7 +13895,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_ranges entry has start address of zero"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
new file mode 100644
index 00000000000..1ddc8d6677b
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
@@ -0,0 +1,21 @@
+/*
+   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/>.  */
+
+void
+foo (void)
+{
+  asm ("foo_label: .globl foo_label");
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
new file mode 100644
index 00000000000..a32c9242c8d
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
@@ -0,0 +1,24 @@
+/*
+   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/>.  */
+
+extern void foo (void);
+
+void
+main (void)
+{
+  asm ("main_label: .globl main_label");
+  foo ();
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
new file mode 100644
index 00000000000..197f077edad
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
@@ -0,0 +1,150 @@
+# 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/>.
+
+# Check that the ".debug_ranges entry has start address of zero" complaint
+# is triggered for a loaded shared lib.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    verbose "Skipping $gdb_test_file_name."
+    return 0
+}
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# The .c files use __attribute__.
+if [get_compiler_info] {
+    return -1
+}
+if !$gcc_compiled {
+    verbose "Skipping $gdb_test_file_name."
+    return 0
+}
+
+standard_testfile .c -shlib.c -dw.S
+
+# Test with both a .debug_ranges section (DWARF 4) and a .debug_rnglists
+# section (DWARF 5).
+
+foreach_with_prefix ranges_sect {ranges rnglists} {
+    set asm_file [standard_output_file ${ranges_sect}-$srcfile3]
+
+    if { $ranges_sect == "ranges" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels ranges_label
+
+	    cu {} {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${ranges_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
+
+	    ranges {is_64 [is_64_target]} {
+		ranges_label: sequence {
+		    base 0
+		    range 0 1
+		}
+	    }
+	}
+    } elseif { $ranges_sect == "rnglists" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels rnglists_label
+
+	    cu {
+		version 5
+	    } {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${rnglists_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
+
+	    rnglists {
+		table {
+		    rnglists_label: list_ {
+			start_end 0 1
+		    }
+		}
+	    }
+	}
+    } else {
+	error "invalid ranges section kind"
+    }
+
+    set lib1 [standard_output_file shr1.sl]
+    set lib_opts "nodebug"
+
+    set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
+    if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
+	untested "failed to compile"
+	return -1
+    }
+
+    set exec_opts [list debug shlib=${lib1}]
+    set sources ${srcdir}/${subdir}/${srcfile}
+    if { [gdb_compile $sources  ${binfile} executable \
+	      $exec_opts] != ""} {
+	untested "failed to compile"
+	return -1
+    }
+
+    clean_restart $binfile
+
+    # Don't load the symbols for $lib1 during runto_main.
+    # Instead, we do this afterwards using "sharedlibrary $lib1".
+    gdb_test_no_output "set auto-solib-add off"
+
+    if { ![runto_main] } {
+	fail "cannot run to main."
+	return -1
+    }
+
+    set complaint_re ".debug_${ranges_sect} entry has start address of zero"
+    set re \
+	"During symbol reading: $complaint_re \\\[in module \[^\r\n\]*\\\]"
+
+    # Test for presence of complaint, with lib1 relocated.
+    with_complaints 1 {
+	gdb_test "sharedlibrary $lib1" $re \
+	    "Zero address complaint - relocated"
+    }
+
+    clean_restart
+    # Test for presence of complaint, with lib1 unrelocated.
+    with_complaints 1 {
+	gdb_load $lib1
+	gdb_assert { [regexp $re.* $gdb_file_cmd_msg] } \
+	    "Zero address complaint - unrelocated"
+    }
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
  2021-07-30 15:25   ` Tom de Vries
@ 2021-07-30 17:50     ` Simon Marchi
  2021-08-01 17:59       ` Tom de Vries
  0 siblings, 1 reply; 8+ messages in thread
From: Simon Marchi @ 2021-07-30 17:50 UTC (permalink / raw)
  To: Tom de Vries, gdb-patches

> Thanks for the review, and the .debug_rnglists addition.
> 
> I've added the .debug_rnglists addition here as well, and added testing
> the complaint when doing gdb_load $lib1, in other words, the unrelocated
> case (which was already passing before this patch).

Thanks, this LGTM.

Note, when merging in master, you can use the Co-Authored-By tag, since
we don't have a ChangeLog file there.

Simon

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
  2021-07-30 17:50     ` Simon Marchi
@ 2021-08-01 17:59       ` Tom de Vries
  2021-08-02 13:09         ` Simon Marchi
  0 siblings, 1 reply; 8+ messages in thread
From: Tom de Vries @ 2021-08-01 17:59 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 998 bytes --]

On 7/30/21 7:50 PM, Simon Marchi wrote:
>> Thanks for the review, and the .debug_rnglists addition.
>>
>> I've added the .debug_rnglists addition here as well, and added testing
>> the complaint when doing gdb_load $lib1, in other words, the unrelocated
>> case (which was already passing before this patch).
> 
> Thanks, this LGTM.
> 
> Note, when merging in master, you can use the Co-Authored-By tag, since
> we don't have a ChangeLog file there.
> 

Ack.

I've updated the test-case to test the complaint both during partial
symtab reading and full symtab reading, and re-tested with a variety of
target board, which required additional updates, and ran into a problem
with .gdb_index, filed as PR28159 - "[gdb/symtab] gdb generates
.gdb_index with only empty hashtable entries, then fails to recognize it
as empty".

The test-case now contains an kfail for this.  I'll submit a patch shortly.

I'm planning to look over the commit message once more tomorrow, and
then commit.

Thanks,
- Tom



[-- Attachment #2: 0001-gdb-symtab-Fix-zero-address-complaint-for-shlib.patch --]
[-- Type: text/x-patch, Size: 13416 bytes --]

[gdb/symtab] Fix zero address complaint for shlib

In PR28004 the following warning / Internal error is reported:
...
$ gdb -q -batch \
    -iex "set sysroot $(pwd -P)/repro" \
    ./repro/gdb \
    ./repro/core \
    -ex bt
  ...
 Program terminated with signal SIGABRT, Aborted.
 #0  0x00007ff8fe8e5d22 in raise () from repro/usr/lib/libc.so.6
 [Current thread is 1 (LWP 1762498)]
 #1  0x00007ff8fe8cf862 in abort () from repro/usr/lib/libc.so.6
 warning: (Internal error: pc 0x7ff8feb2c21d in read in psymtab, \
           but not in symtab.)
 warning: (Internal error: pc 0x7ff8feb2c218 in read in psymtab, \
           but not in symtab.)
  ...
 #2  0x00007ff8feb2c21e in __gnu_debug::_Error_formatter::_M_error() const \
   [clone .cold] (warning: (Internal error: pc 0x7ff8feb2c21d in read in \
   psymtab, but not in symtab.)

) from repro/usr/lib/libstdc++.so.6
...

The warning is about the following:
- in find_pc_sect_compunit_symtab we try to find the address
  (0x7ff8feb2c218 / 0x7ff8feb2c21d) in the symtabs.
- that fails, so we try again in the partial symtabs.
- we find a matching partial symtab
- however, the partial symtab has a matching symtab, so
  we should have found a matching symtab in the first step.

The addresses are:
...
(gdb) info sym 0x7ff8feb2c218
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] in \
  section .text of repro/usr/lib/libstdc++.so.6
(gdb) info sym 0x7ff8feb2c21d
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] + 5 in \
  section .text of repro/usr/lib/libstdc++.so.6
...
which correspond to unrelocated addresses 0x9c218 and 0x9c21d:
...
$ nm -C  repro/usr/lib/libstdc++.so.6.0.29 | grep 000000000009c218
000000000009c218 t __gnu_debug::_Error_formatter::_M_error() const \
  [clone .cold]
...

The unrelocated addresses can be found in the partial symbols addresss map:
...
(gdb) set $map = (addrmap_fixed *)m_partial_symtabs->psymtabs_addrmap
(gdb) p /x $map->transitions[24]
$47 = {addr = 0x9989c, value = 0x231d1b0}
(gdb) p /x $map->transitions[25]
$48 = {addr = 0xa2170, value = 0x5439980}
...
and indeed we do:
...
(gdb) p ps
$1 = (partial_symtab *) 0x231d1b0
...
but not in the symbols address map:
...
(gdb) set $symtab = ps->get_compunit_symtab (objfile)
(gdb) set $map = (addrmap_fixed *)$symtab.blockvector.map
(gdb) p /x $map.transitions[20]
$42 = {addr = 0x7ff8feb2993a, value = 0x0}
(gdb) p /x $map.transitions[21]
$43 = {addr = 0x7ff8feb322b0, value = 0x6155ef0}
...

The reason for the difference between the two address maps (who are based on
the same data), is this code in dwarf2_rnglists_process:
...
      /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
      if (range_beginning + baseaddr == 0
          && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_rnglists entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
          continue;
        }
...
which triggers for the partial symbol table case (with unrelocated addresses),
but not for the symbol table case (with relocated addresses).

The difference is that in the latter case, baseaddr (initialized from
objfile->text_section_offset ()) isn't 0.

Fix this by removing the baseaddr part from the condition.  Same for
dwarf2_ranges_process.

The effect is that:
- the complaint is triggered, and
- the warning / Internal error is no longer triggered.

Tested on x86_64-linux.

Co-Authored-By: Simon Marchi <simon.marchi@polymtl.ca>

gdb/ChangeLog:

2021-07-29  Simon Marchi  <simon.marchi@polymtl.ca>
	    Tom de Vries  <tdevries@suse.de>

	PR symtab/28004
	* gdb/dwarf2/read.c (dwarf2_rnglists_process, dwarf2_ranges_process):
	Fix zero address complaint.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp: New file.

---
 gdb/dwarf2/read.c                               |  10 +-
 gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c |  21 +++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.c       |  24 +++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp     | 194 ++++++++++++++++++++++++
 4 files changed, 241 insertions(+), 8 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 6f1b453ef45..de84c47b626 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -13631,7 +13631,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   /* Base address selection entry.  */
   gdb::optional<CORE_ADDR> base;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
   bool overflow = false;
   ULONGEST addr_index;
   struct dwarf2_section_info *rnglists_section;
@@ -13648,8 +13647,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
     }
   buffer = rnglists_section->buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       /* Initialize it due to a false compiler warning.  */
@@ -13791,7 +13788,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_rnglists entry has start address of zero"
@@ -13833,7 +13830,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
   gdb::optional<CORE_ADDR> base;
   unsigned int dummy;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
 
   if (cu_header->version >= 5)
     return dwarf2_rnglists_process (offset, cu, tag, callback);
@@ -13849,8 +13845,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
     }
   buffer = per_objfile->per_bfd->ranges.buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       CORE_ADDR range_beginning, range_end;
@@ -13901,7 +13895,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_ranges entry has start address of zero"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
new file mode 100644
index 00000000000..1ddc8d6677b
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
@@ -0,0 +1,21 @@
+/*
+   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/>.  */
+
+void
+foo (void)
+{
+  asm ("foo_label: .globl foo_label");
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
new file mode 100644
index 00000000000..a32c9242c8d
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
@@ -0,0 +1,24 @@
+/*
+   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/>.  */
+
+extern void foo (void);
+
+void
+main (void)
+{
+  asm ("main_label: .globl main_label");
+  foo ();
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
new file mode 100644
index 00000000000..7b46c93d9b5
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
@@ -0,0 +1,194 @@
+# 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/>.
+
+# Check that the ".debug_ranges entry has start address of zero" complaint
+# is triggered for a loaded shared lib.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    verbose "Skipping $gdb_test_file_name."
+    return 0
+}
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+# The .c files use __attribute__.
+if [get_compiler_info] {
+    return -1
+}
+if !$gcc_compiled {
+    verbose "Skipping $gdb_test_file_name."
+    return 0
+}
+
+standard_testfile .c -shlib.c -dw.S
+
+# Test with both a .debug_ranges section (DWARF 4) and a .debug_rnglists
+# section (DWARF 5).
+
+foreach_with_prefix ranges_sect {ranges rnglists} {
+    set asm_file [standard_output_file ${ranges_sect}-$srcfile3]
+
+    if { $ranges_sect == "ranges" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels ranges_label
+
+	    cu {} {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${ranges_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
+
+	    ranges {is_64 [is_64_target]} {
+		ranges_label: sequence {
+		    base 0
+		    range 0 1
+		}
+	    }
+	}
+    } elseif { $ranges_sect == "rnglists" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels rnglists_label
+
+	    cu {
+		version 5
+	    } {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${rnglists_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
+
+	    rnglists {
+		table {
+		    rnglists_label: list_ {
+			start_end 0 1
+		    }
+		}
+	    }
+	}
+    } else {
+	error "invalid ranges section kind"
+    }
+
+    set lib1 [standard_output_file shr1.sl]
+    set lib_opts "nodebug"
+
+    set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
+    if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
+	untested "failed to compile"
+	return -1
+    }
+
+    set exec_opts [list debug shlib=${lib1}]
+    set sources ${srcdir}/${subdir}/${srcfile}
+    if { [gdb_compile $sources  ${binfile} executable \
+	      $exec_opts] != ""} {
+	untested "failed to compile"
+	return -1
+    }
+
+    clean_restart $binfile
+
+    set readnow_p [readnow]
+
+    # Don't load the symbols for $lib1 during runto_main.
+    # Instead, we do this afterwards using "sharedlibrary $lib1".
+    gdb_test_no_output "set auto-solib-add off"
+
+    if { ![runto_main] } {
+	fail "cannot run to main."
+	return -1
+    }
+
+    set complaint_re ".debug_${ranges_sect} entry has start address of zero"
+    set re \
+	"During symbol reading: $complaint_re \\\[in module \[^\r\n\]*\\\]"
+
+    # Test for presence of complaint, with lib1 relocated.
+    with_complaints 1 {
+	set test "Zero address complaint - relocated - psymtab"
+	set have_complaint 0
+	gdb_test_multiple "sharedlibrary $lib1" $test {
+	    -re -wrap $re {
+		set have_complaint 1
+	    }
+	    -re -wrap "" {
+	    }
+	}
+
+	if { $have_complaint } {
+	    pass $test
+	} else {
+	    set index [have_index $lib1]
+	    if { $index == "gdb_index" } {
+		kfail symtab/28159 $test
+	    } else {
+		fail $test
+	    }
+	}
+    }
+
+    if { ! $readnow_p } {
+	with_complaints 1 {
+	    gdb_test "maint expand-symtabs $srcfile2" $re \
+		"Zero address complaint - relocated - symtab"
+	}
+    }
+
+    clean_restart
+    # Test for presence of complaint, with lib1 unrelocated.
+    with_complaints 1 {
+	gdb_load $lib1
+	set test "Zero address complaint - unrelocated - psymtab"
+	set have_complaint [regexp $re.* $gdb_file_cmd_msg]
+	if { $have_complaint } {
+	    pass $test
+	} else {
+	    set index [have_index $lib1]
+	    if { $index == "gdb_index" } {
+		kfail symtab/28159 $test
+	    } else {
+		fail $test
+	    }
+	}
+    }
+
+    if { ! $readnow_p } {
+	with_complaints 1 {
+	    gdb_test "maint expand-symtabs $srcfile2" $re \
+		"Zero address complaint - unrelocated - symtab"
+	}
+    }
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
  2021-08-01 17:59       ` Tom de Vries
@ 2021-08-02 13:09         ` Simon Marchi
  2021-08-06 14:43           ` Tom de Vries
  0 siblings, 1 reply; 8+ messages in thread
From: Simon Marchi @ 2021-08-02 13:09 UTC (permalink / raw)
  To: Tom de Vries, gdb-patches

Where it says:

> +# The .c files use __attribute__.
> +if [get_compiler_info] {
> +    return -1
> +}

The .c files don't seem to use __attribute__.

I'm also wondering why we use this for these tests:

> +if !$gcc_compiled {
> +    verbose "Skipping $gdb_test_file_name."
> +    return 0
> +}

The test runs fine with CC_FOR_TARGET=clang, for example (with the trivial
fix to make main return int).

Simon


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib
  2021-08-02 13:09         ` Simon Marchi
@ 2021-08-06 14:43           ` Tom de Vries
  0 siblings, 0 replies; 8+ messages in thread
From: Tom de Vries @ 2021-08-06 14:43 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 618 bytes --]

On 8/2/21 3:09 PM, Simon Marchi wrote:
> Where it says:
> 
>> +# The .c files use __attribute__.
>> +if [get_compiler_info] {
>> +    return -1
>> +}
> 
> The .c files don't seem to use __attribute__.
> 
> I'm also wondering why we use this for these tests:
> 
>> +if !$gcc_compiled {
>> +    verbose "Skipping $gdb_test_file_name."
>> +    return 0
>> +}
> 
> The test runs fine with CC_FOR_TARGET=clang, for example (with the trivial
> fix to make main return int).

Ack, fixed.

After doing some further analysis and filing PR28200, I'm finally happy
with the commit message.

Will commit shortly.

Thanks,
- Tom



[-- Attachment #2: 0001-gdb-symtab-Fix-zero-address-complaint-for-shlib.patch --]
[-- Type: text/x-patch, Size: 14448 bytes --]

[gdb/symtab] Fix zero address complaint for shlib

In PR28004 the following warning / Internal error is reported:
...
$ gdb -q -batch \
    -iex "set sysroot $(pwd -P)/repro" \
    ./repro/gdb \
    ./repro/core \
    -ex bt
  ...
 Program terminated with signal SIGABRT, Aborted.
 #0  0x00007ff8fe8e5d22 in raise () from repro/usr/lib/libc.so.6
 [Current thread is 1 (LWP 1762498)]
 #1  0x00007ff8fe8cf862 in abort () from repro/usr/lib/libc.so.6
 warning: (Internal error: pc 0x7ff8feb2c21d in read in psymtab, \
           but not in symtab.)
 warning: (Internal error: pc 0x7ff8feb2c218 in read in psymtab, \
           but not in symtab.)
  ...
 #2  0x00007ff8feb2c21e in __gnu_debug::_Error_formatter::_M_error() const \
   [clone .cold] (warning: (Internal error: pc 0x7ff8feb2c21d in read in \
   psymtab, but not in symtab.)

) from repro/usr/lib/libstdc++.so.6
...

The warning is about the following:
- in find_pc_sect_compunit_symtab we try to find the address
  (0x7ff8feb2c218 / 0x7ff8feb2c21d) in the symtabs.
- that fails, so we try again in the partial symtabs.
- we find a matching partial symtab
- however, the partial symtab has a full symtab, so
  we should have found a matching symtab in the first step.

The addresses are:
...
(gdb) info sym 0x7ff8feb2c218
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] in \
  section .text of repro/usr/lib/libstdc++.so.6
(gdb) info sym 0x7ff8feb2c21d
__gnu_debug::_Error_formatter::_M_error() const [clone .cold] + 5 in \
  section .text of repro/usr/lib/libstdc++.so.6
...
which correspond to unrelocated addresses 0x9c218 and 0x9c21d:
...
$ nm -C  repro/usr/lib/libstdc++.so.6.0.29 | grep 000000000009c218
000000000009c218 t __gnu_debug::_Error_formatter::_M_error() const \
  [clone .cold]
...
which belong to function __gnu_debug::_Error_formatter::_M_error() in
/build/gcc/src/gcc/libstdc++-v3/src/c++11/debug.cc.

The partial symtab that is found for the addresses is instead the one for
/build/gcc/src/gcc/libstdc++-v3/src/c++98/bitmap_allocator.cc, which is
incorrect.

This happens as follows.

The bitmap_allocator.cc CU has DW_AT_ranges at .debug_rnglist offset 0x4b50:
...
    00004b50 0000000000000000 0000000000000056
    00004b5a 00000000000a4790 00000000000a479c
    00004b64 00000000000a47a0 00000000000a47ac
...

When reading the first range 0x0..0x56, it doesn't trigger the "start address
of zero" complaint here:
...
      /* A not-uncommon case of bad debug info.
         Don't pollute the addrmap with bad data.  */
      if (range_beginning + baseaddr == 0
          && !per_objfile->per_bfd->has_section_at_zero)
        {
          complaint (_(".debug_rnglists entry has start address of zero"
                       " [in module %s]"), objfile_name (objfile));
          continue;
        }
...
because baseaddr != 0, which seems incorrect given that when loading the
shared library individually in gdb (and consequently baseaddr == 0), we do see
the complaint.

Consequently, we run into this case in dwarf2_get_pc_bounds:
...
  if (low == 0 && !per_objfile->per_bfd->has_section_at_zero)
    return PC_BOUNDS_INVALID;
...
which then results in this code in process_psymtab_comp_unit_reader being
called with cu_bounds_kind == PC_BOUNDS_INVALID, which sets the set_addrmap
argument to 1:
...
      scan_partial_symbols (first_die, &lowpc, &highpc,
                            cu_bounds_kind <= PC_BOUNDS_INVALID, cu);
...
and consequently, the CU addrmap gets build using address info from the
functions.

During that process, addrmap_set_empty is called with a range that includes
0x9c218 and 0x9c21d:
...
(gdb) p /x start
$7 = 0x9989c
(gdb) p /x end_inclusive
$8 = 0xb200d
...
but it's called for a function at DIE 0x54153 with DW_AT_ranges at 0x40ae:
...
    000040ae 00000000000b1ee0 00000000000b200e
    000040b9 000000000009989c 00000000000998c4
    000040c3 <End of list>
...
and neither range includes 0x9c218 and 0x9c21d.

This is caused by this code in partial_die_info::read:
...
            if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu,
                                    nullptr, tag))
             has_pc_info = 1;
...
which pretends that the function is located at addresses 0x9989c..0xb200d,
which is indeed not the case.

This patch fixes the first problem encountered: fix the "start address of
zero" complaint warning by removing the baseaddr part from the condition.
Same for dwarf2_ranges_process.

The effect is that:
- the complaint is triggered, and
- the warning / Internal error is no longer triggered.

This does not fix the observed problem in partial_die_info::read, which is
filed as PR28200.

Tested on x86_64-linux.

Co-Authored-By: Simon Marchi <simon.marchi@polymtl.ca>

gdb/ChangeLog:

2021-07-29  Simon Marchi  <simon.marchi@polymtl.ca>
	    Tom de Vries  <tdevries@suse.de>

	PR symtab/28004
	* gdb/dwarf2/read.c (dwarf2_rnglists_process, dwarf2_ranges_process):
	Fix zero address complaint.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.c: New test.
	* gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp: New file.

---
 gdb/dwarf2/read.c                               |  10 +-
 gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c |  21 +++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.c       |  24 +++
 gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp     | 185 ++++++++++++++++++++++++
 4 files changed, 232 insertions(+), 8 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index acabee3315f..bac02b5a1bd 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -13631,7 +13631,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   /* Base address selection entry.  */
   gdb::optional<CORE_ADDR> base;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
   bool overflow = false;
   ULONGEST addr_index;
   struct dwarf2_section_info *rnglists_section;
@@ -13648,8 +13647,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
     }
   buffer = rnglists_section->buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       /* Initialize it due to a false compiler warning.  */
@@ -13791,7 +13788,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_rnglists entry has start address of zero"
@@ -13833,7 +13830,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
   gdb::optional<CORE_ADDR> base;
   unsigned int dummy;
   const gdb_byte *buffer;
-  CORE_ADDR baseaddr;
 
   if (cu_header->version >= 5)
     return dwarf2_rnglists_process (offset, cu, tag, callback);
@@ -13849,8 +13845,6 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
     }
   buffer = per_objfile->per_bfd->ranges.buffer + offset;
 
-  baseaddr = objfile->text_section_offset ();
-
   while (1)
     {
       CORE_ADDR range_beginning, range_end;
@@ -13901,7 +13895,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning + baseaddr == 0
+      if (range_beginning == 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_ranges entry has start address of zero"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
new file mode 100644
index 00000000000..1ddc8d6677b
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range-shlib.c
@@ -0,0 +1,21 @@
+/*
+   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/>.  */
+
+void
+foo (void)
+{
+  asm ("foo_label: .globl foo_label");
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
new file mode 100644
index 00000000000..894a04df786
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.c
@@ -0,0 +1,24 @@
+/*
+   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/>.  */
+
+extern void foo (void);
+
+int
+main (void)
+{
+  asm ("main_label: .globl main_label");
+  foo ();
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
new file mode 100644
index 00000000000..4f2ac0fe77c
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-zero-range.exp
@@ -0,0 +1,185 @@
+# 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/>.
+
+# Check that the ".debug_ranges entry has start address of zero" complaint
+# is triggered for a loaded shared lib.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    verbose "Skipping $gdb_test_file_name."
+    return 0
+}
+
+if {[skip_shlib_tests]} {
+    return 0
+}
+
+standard_testfile .c -shlib.c -dw.S
+
+# Test with both a .debug_ranges section (DWARF 4) and a .debug_rnglists
+# section (DWARF 5).
+
+foreach_with_prefix ranges_sect {ranges rnglists} {
+    set asm_file [standard_output_file ${ranges_sect}-$srcfile3]
+
+    if { $ranges_sect == "ranges" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels ranges_label
+
+	    cu {} {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${ranges_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
+
+	    ranges {is_64 [is_64_target]} {
+		ranges_label: sequence {
+		    base 0
+		    range 0 1
+		}
+	    }
+	}
+    } elseif { $ranges_sect == "rnglists" } {
+	Dwarf::assemble $asm_file {
+	    global srcdir subdir srcfile2
+	    declare_labels rnglists_label
+
+	    cu {
+		version 5
+	    } {
+		compile_unit {
+		    {language @DW_LANG_C}
+		    {name $srcfile2}
+		    {ranges ${rnglists_label} DW_FORM_sec_offset}
+		} {
+		    subprogram {
+			{external 1 flag}
+			{name foo}
+		    }
+		}
+	    }
+
+	    rnglists {
+		table {
+		    rnglists_label: list_ {
+			start_end 0 1
+		    }
+		}
+	    }
+	}
+    } else {
+	error "invalid ranges section kind"
+    }
+
+    set lib1 [standard_output_file shr1.sl]
+    set lib_opts "nodebug"
+
+    set sources [list ${srcdir}/${subdir}/$srcfile2 $asm_file]
+    if { [gdb_compile_shlib $sources ${lib1} $lib_opts] != "" } {
+	untested "failed to compile"
+	return -1
+    }
+
+    set exec_opts [list debug shlib=${lib1}]
+    set sources ${srcdir}/${subdir}/${srcfile}
+    if { [gdb_compile $sources  ${binfile} executable \
+	      $exec_opts] != ""} {
+	untested "failed to compile"
+	return -1
+    }
+
+    clean_restart $binfile
+
+    set readnow_p [readnow]
+
+    # Don't load the symbols for $lib1 during runto_main.
+    # Instead, we do this afterwards using "sharedlibrary $lib1".
+    gdb_test_no_output "set auto-solib-add off"
+
+    if { ![runto_main] } {
+	fail "cannot run to main."
+	return -1
+    }
+
+    set complaint_re ".debug_${ranges_sect} entry has start address of zero"
+    set re \
+	"During symbol reading: $complaint_re \\\[in module \[^\r\n\]*\\\]"
+
+    # Test for presence of complaint, with lib1 relocated.
+    with_complaints 1 {
+	set test "Zero address complaint - relocated - psymtab"
+	set have_complaint 0
+	gdb_test_multiple "sharedlibrary $lib1" $test {
+	    -re -wrap $re {
+		set have_complaint 1
+	    }
+	    -re -wrap "" {
+	    }
+	}
+
+	if { $have_complaint } {
+	    pass $test
+	} else {
+	    set index [have_index $lib1]
+	    if { $index == "gdb_index" } {
+		kfail symtab/28159 $test
+	    } else {
+		fail $test
+	    }
+	}
+    }
+
+    if { ! $readnow_p } {
+	with_complaints 1 {
+	    gdb_test "maint expand-symtabs $srcfile2" $re \
+		"Zero address complaint - relocated - symtab"
+	}
+    }
+
+    clean_restart
+    # Test for presence of complaint, with lib1 unrelocated.
+    with_complaints 1 {
+	gdb_load $lib1
+	set test "Zero address complaint - unrelocated - psymtab"
+	set have_complaint [regexp $re.* $gdb_file_cmd_msg]
+	if { $have_complaint } {
+	    pass $test
+	} else {
+	    set index [have_index $lib1]
+	    if { $index == "gdb_index" } {
+		kfail symtab/28159 $test
+	    } else {
+		fail $test
+	    }
+	}
+    }
+
+    if { ! $readnow_p } {
+	with_complaints 1 {
+	    gdb_test "maint expand-symtabs $srcfile2" $re \
+		"Zero address complaint - unrelocated - symtab"
+	}
+    }
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-08-06 14:43 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-29 21:23 [PATCH master + 11][gdb/symtab] Fix zero address complaint for shlib Tom de Vries
2021-07-30  1:25 ` Simon Marchi
2021-07-30  1:48   ` Simon Marchi
2021-07-30 15:25   ` Tom de Vries
2021-07-30 17:50     ` Simon Marchi
2021-08-01 17:59       ` Tom de Vries
2021-08-02 13:09         ` Simon Marchi
2021-08-06 14:43           ` Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).