[6/7] gdb/testsuite/gdb.debuginfod: Add lazy downloading tests

Message ID 20230227194212.348003-6-amerey@redhat.com
State New
Headers
Series [1/7] gdb/debuginfod: Add debuginfod_section_query |

Commit Message

Aaron Merey Feb. 27, 2023, 7:42 p.m. UTC
  Add some tests for 'set debuginfod enabled lazy', .gdb_index downloading
and deferred debuginfo downloading.
---
 .../gdb.debuginfod/fetch_src_and_symbols.exp  | 58 +++++++++++++++++++
 gdb/testsuite/gdb.debuginfod/libsection.c     | 24 ++++++++
 gdb/testsuite/gdb.debuginfod/section.c        | 28 +++++++++
 3 files changed, 110 insertions(+)
 create mode 100644 gdb/testsuite/gdb.debuginfod/libsection.c
 create mode 100644 gdb/testsuite/gdb.debuginfod/section.c
  

Comments

Andrew Burgess May 2, 2023, 3:48 p.m. UTC | #1
Aaron Merey via Gdb-patches <gdb-patches@sourceware.org> writes:

> Add some tests for 'set debuginfod enabled lazy', .gdb_index downloading
> and deferred debuginfo downloading.
> ---
>  .../gdb.debuginfod/fetch_src_and_symbols.exp  | 58 +++++++++++++++++++
>  gdb/testsuite/gdb.debuginfod/libsection.c     | 24 ++++++++
>  gdb/testsuite/gdb.debuginfod/section.c        | 28 +++++++++
>  3 files changed, 110 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.debuginfod/libsection.c
>  create mode 100644 gdb/testsuite/gdb.debuginfod/section.c

I compile GDB with both '-D_GLIBCXX_DEBUG=1' and
'-D_GLIBCXX_DEBUG_PEDANTIC=1' defined.

After applying this series I see the following GDB crash when running
the fetch_src_and_symbols.exp test:

  (gdb) file
  No executable file now.
  /usr/include/c++/9/debug/safe_iterator.h:597:
  In function:
      __gnu_debug::_Safe_iterator<_Iterator, _Sequence, 
      std::bidirectional_iterator_tag>& __gnu_debug::_Safe_iterator<_Iterator, 
      _Sequence, std::bidirectional_iterator_tag>::operator--() [with 
      _Iterator = std::__cxx1998::_List_iterator<std::unique_ptr<objfile> >; 
      _Sequence = std::__debug::list<std::unique_ptr<objfile> >]
  
  Error: attempt to decrement a dereferenceable (start-of-sequence) iterator.
  
  Objects involved in the operation:
      iterator "this" @ 0x0x7ffebcfec598 {
        type = std::__cxx1998::_List_iterator<std::unique_ptr<objfile, std::default_delete<objfile> > > (mutable iterato>
        state = dereferenceable (start-of-sequence);
        references sequence with type 'std::__debug::list<std::unique_ptr<objfile, std::default_delete<objfile> >, std::>
      }
  
  
  Fatal signal: Aborted
  ----- Backtrace -----
  0x603500 gdb_internal_backtrace_1
          ../../src.dev-4/gdb/bt-utils.c:122
  0x6035a3 _Z22gdb_internal_backtracev
          ../../src.dev-4/gdb/bt-utils.c:168
  0x8a7732 handle_fatal_signal
          ../../src.dev-4/gdb/event-top.c:880
  0x7fd0b9c686af ???
  0x7fd0b9c68625 ???
  0x7fd0b9c518d8 ???
  0x7fd0b9ff5d18 ???
  0x9eae05 _ZN11__gnu_debug14_Safe_iteratorINSt9__cxx199814_List_iteratorISt10unique_ptrI7objfileSt14default_deleteIS4_E>
          /usr/include/c++/9/debug/safe_iterator.h:597
  0x9e9843 _ZN27unwrapping_reverse_iteratorIN11__gnu_debug14_Safe_iteratorINSt9__cxx199814_List_iteratorISt10unique_ptrI>
          ../../src.dev-4/gdb/progspace.h:116
  0x9e840a _ZN22reverse_iterator_rangeI27unwrapping_reverse_iteratorIN11__gnu_debug14_Safe_iteratorINSt9__cxx199814_List>
          ../../src.dev-4/gdb/../gdbsupport/iterator-range.h:85
  0x9e7af3 _ZN13program_space13objfiles_safeEv
          ../../src.dev-4/gdb/progspace.h:280
  0xb5386c _Z20objfile_purge_solibsv
          ../../src.dev-4/gdb/objfiles.c:804
  0xd93da0 _Z19no_shared_librariesPKci
          ../../src.dev-4/gdb/solib.c:1285
  0xdeb0a4 _Z17symbol_file_cleari
          ../../src.dev-4/gdb/symfile.c:1234
  0xdec299 _Z19symbol_file_commandPKci
          ../../src.dev-4/gdb/symfile.c:1628
  0x8aab49 file_command
          ../../src.dev-4/gdb/exec.c:554
  0x6800d0 do_simple_func
          ../../src.dev-4/gdb/cli/cli-decode.c:95
  0x685145 _Z8cmd_funcP16cmd_list_elementPKci
          ../../src.dev-4/gdb/cli/cli-decode.c:2735
  0xe90e33 _Z15execute_commandPKci
          ../../src.dev-4/gdb/top.c:572
  0x8a6eea _Z15command_handlerPKc
          ../../src.dev-4/gdb/event-top.c:543
  0x8a73f3 _Z20command_line_handlerOSt10unique_ptrIcN3gdb13xfree_deleterIcEEE
          ../../src.dev-4/gdb/event-top.c:779


Thanks,
Andrew






>
> diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
> index 8158c5c3cc6..fc7e4b685dc 100644
> --- a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
> +++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
> @@ -42,6 +42,23 @@ if { [gdb_compile "$sourcetmp" "${binfile}2" executable {debug build-id}] != ""
>      return -1
>  }
>  
> +set sectfile "section"
> +set sectsrc $srcdir/$subdir/section.c
> +set sectexec [standard_output_file $sectfile]
> +
> +set libfile "libsection"
> +set libsrc $srcdir/$subdir/$libfile.c
> +set lib_sl [standard_output_file $libfile.sl]
> +
> +set lib_opts [list debug build-id ]
> +set exec_opts [list debug build-id shlib=$lib_sl]
> +
> +if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != ""
> +     || [gdb_compile $sectsrc $sectexec executable $exec_opts] != "" } {
> +    untested "failed to compile"
> +    return -1
> +}
> +
>  # Write some assembly that just has a .gnu_debugaltlink section.
>  # Copied from testsuite/gdb.dwarf2/dwzbuildid.exp.
>  proc write_just_debugaltlink {filename dwzname buildid} {
> @@ -94,6 +111,7 @@ proc write_dwarf_file {filename buildid {value 99}} {
>  }
>  
>  set corefile [standard_output_file "corefile"]
> +set lazy_support -1
>  
>  # Setup the global variable DEBUGDIR as a directory containing the
>  # debug information for the test executable.
> @@ -103,6 +121,8 @@ set corefile [standard_output_file "corefile"]
>  # running.
>  proc_with_prefix no_url { } {
>      global binfile outputdir debugdir
> +    global sectexec lib_sl libfile lazy_support
> +    global gdb_prompt
>  
>      setenv DEBUGINFOD_URLS ""
>  
> @@ -119,11 +139,18 @@ proc_with_prefix no_url { } {
>  	return -1
>      }
>  
> +    if { [gdb_gnu_strip_debug $lib_sl ""] != 0} {
> +	fail "strip shlib debuginfo"
> +	return -1
> +    }
> +
>      set debugdir [standard_output_file "debug"]
>      set debuginfo [standard_output_file "fetch_src_and_symbols.debug"]
> +    set debuginfo_shlib [standard_output_file $libfile.sl.debug]
>  
>      file mkdir $debugdir
>      file rename -force $debuginfo $debugdir
> +    file rename -force $debuginfo_shlib $debugdir
>  
>      # Test that GDB cannot find symbols without debuginfod.
>      clean_restart $binfile
> @@ -171,6 +198,25 @@ proc_with_prefix no_url { } {
>  
>      clean_restart
>      gdb_test "core $::corefile" ".*in ?? ().*" "file [file tail $::corefile]"
> +    clean_restart
> +
> +    # Check for lazy downloading support.
> +    gdb_test_multiple "set debuginfod enabled lazy" "check for lazy" {
> +	-re ".*lazy downloading is not compiled into GDB.*\n.*${gdb_prompt} $" {
> +	    set lazy_support 0
> +	}
> +	-re ".*${gdb_prompt} $" {
> +	    set lazy_support 1
> +	}
> +    }
> +
> +    if {$lazy_support == 1} {
> +	gdb_test "file $sectexec" "" "file [file tail $sectexec] file no url"
> +	gdb_test "start" "" "file [file tail $sectexec] start no url"
> +	gdb_test "info sharedlibrary" ".*Yes \\(\\*\\).*libsection.*" "lib no debug"
> +    } else {
> +	untested "lazy support no_url"
> +    }
>  }
>  
>  # Test that GDB prints the debuginfod URLs when loading files.  URLS
> @@ -208,6 +254,7 @@ proc disable_delete_breakpoints {} {
>  # expected debug information.
>  proc_with_prefix local_url { } {
>      global binfile outputdir debugdir db
> +    global sectexec lib_sl libfile lazy_support
>  
>      set url [start_debuginfod $db $debugdir]
>      if { $url == "" } {
> @@ -256,6 +303,17 @@ proc_with_prefix local_url { } {
>  	"file [file tail ${binfile}_alt.o]" \
>  	$enable_debuginfod_question "y"
>  
> +    if {$lazy_support == 1} {
> +	# GDB should now download .gdb_index.
> +	clean_restart
> +	gdb_test "set debuginfod enabled lazy" "" "set lazy urls"
> +	gdb_test "file $sectexec" "" "file [file tail $sectexec] file urls"
> +	set res ".*Download.*\.gdb_index.*libsection.*\r\nDownload.*debug info.*libsection.*"
> +	gdb_test "start $sectexec" $res "file [file tail $sectexec] start urls"
> +    } else {
> +	untested "lazy support urls"
> +    }
> +
>      # Configure debuginfod with commands.
>      unsetenv DEBUGINFOD_URLS
>      clean_restart
> diff --git a/gdb/testsuite/gdb.debuginfod/libsection.c b/gdb/testsuite/gdb.debuginfod/libsection.c
> new file mode 100644
> index 00000000000..510f9205282
> --- /dev/null
> +++ b/gdb/testsuite/gdb.debuginfod/libsection.c
> @@ -0,0 +1,24 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2020-2023 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 <stdio.h>
> +
> +void
> +libsection_test ()
> +{
> +  printf ("In libsection\n");
> +}
> diff --git a/gdb/testsuite/gdb.debuginfod/section.c b/gdb/testsuite/gdb.debuginfod/section.c
> new file mode 100644
> index 00000000000..3598896c1bc
> --- /dev/null
> +++ b/gdb/testsuite/gdb.debuginfod/section.c
> @@ -0,0 +1,28 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2020-2023 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 <fcntl.h>
> +
> +extern void libsection_test ();
> +
> +int
> +main()
> +{
> +  (void) open ("", 0);
> +  libsection_test ();
> +  return 0;
> +}
> -- 
> 2.39.2
  
Aaron Merey May 2, 2023, 4:24 p.m. UTC | #2
Hi Andrew,

On Tue, May 2, 2023 at 11:48 AM Andrew Burgess <aburgess@redhat.com> wrote:
> I compile GDB with both '-D_GLIBCXX_DEBUG=1' and
> '-D_GLIBCXX_DEBUG_PEDANTIC=1' defined.
>
> After applying this series I see the following GDB crash when running
> the fetch_src_and_symbols.exp test:
>
>   (gdb) file
>   No executable file now.
>   /usr/include/c++/9/debug/safe_iterator.h:597:
>   In function:
>       __gnu_debug::_Safe_iterator<_Iterator, _Sequence,
>       std::bidirectional_iterator_tag>& __gnu_debug::_Safe_iterator<_Iterator,
>       _Sequence, std::bidirectional_iterator_tag>::operator--() [with
>       _Iterator = std::__cxx1998::_List_iterator<std::unique_ptr<objfile> >;
>       _Sequence = std::__debug::list<std::unique_ptr<objfile> >]
>
>   Error: attempt to decrement a dereferenceable (start-of-sequence) iterator.

Thanks for spotting this. It looks like the culprit is from the following change
in patch 5/7 [1]:

diff --git a/gdbsupport/iterator-range.h b/gdbsupport/iterator-range.h
index e934f5ebf01..853ebb9074a 100644
--- a/gdbsupport/iterator-range.h
+++ b/gdbsupport/iterator-range.h
@@ -61,4 +61,49 @@ struct iterator_range
+template <typename IteratorType>
+struct reverse_iterator_range
+{
+  using iterator = IteratorType;
+
+  /* Create a reverse iterator range using explicit BEGIN and END
iterators.  */
+  template <typename... Args>
+  reverse_iterator_range (IteratorType begin, IteratorType end)
+    : m_begin (std::move (end)), m_end (std::move (begin))
+  {
+    if (m_begin != m_end)
+      {
+ /* M_BEGIN is the base iterator's one-past-the-end.  Increment it
+   so it points to the ranges's last element.  */
+ ++m_begin;
+
+ /* M_END points to the range's first element.  Increment it so it's
+   one-past-the-end.  */
+ ++m_end;
+      }
+  }
[...]

'++m_end' has the effect of decrementing a std::list begin() iterator, though it
should never be dereferenced. I'll fix this and post a follow up to patch 5/7.

Aaron

[1] https://sourceware.org/pipermail/gdb-patches/2023-April/199076.html
  
Andrew Burgess May 24, 2023, 10:12 a.m. UTC | #3
Aaron Merey via Gdb-patches <gdb-patches@sourceware.org> writes:

> Add some tests for 'set debuginfod enabled lazy', .gdb_index downloading
> and deferred debuginfo downloading.
> ---
>  .../gdb.debuginfod/fetch_src_and_symbols.exp  | 58 +++++++++++++++++++
>  gdb/testsuite/gdb.debuginfod/libsection.c     | 24 ++++++++
>  gdb/testsuite/gdb.debuginfod/section.c        | 28 +++++++++
>  3 files changed, 110 insertions(+)
>  create mode 100644 gdb/testsuite/gdb.debuginfod/libsection.c
>  create mode 100644 gdb/testsuite/gdb.debuginfod/section.c
>
> diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
> index 8158c5c3cc6..fc7e4b685dc 100644
> --- a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
> +++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
> @@ -42,6 +42,23 @@ if { [gdb_compile "$sourcetmp" "${binfile}2" executable {debug build-id}] != ""
>      return -1
>  }
>  
> +set sectfile "section"
> +set sectsrc $srcdir/$subdir/section.c
> +set sectexec [standard_output_file $sectfile]
> +
> +set libfile "libsection"
> +set libsrc $srcdir/$subdir/$libfile.c
> +set lib_sl [standard_output_file $libfile.sl]
> +
> +set lib_opts [list debug build-id ]
> +set exec_opts [list debug build-id shlib=$lib_sl]
> +
> +if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != ""
> +     || [gdb_compile $sectsrc $sectexec executable $exec_opts] != "" } {
> +    untested "failed to compile"
> +    return -1
> +}

I'm really not a fan of either having a separate "add tests" commit,
this makes it so much harder in the future to track down which test
corresponds to a particular change.  Nor am I a fan of having this one
test script fetch_src_and_symbols.exp, into which all debuginfod tests
just keep getting added.

I already made an attempt to factor out some of the support
functionality into lib/debuginfod-support.exp, and it would be great to
see more functionality added in there so that it becomes easier to add
new debuginfod tests.

I mean, it's fine, if the new test makes use of an existing binary and
you're just running some extra commands as part of an existing test
script, but for me the red flag is that you have a whole new source file
which you compile, that indicates (to me) that this should be a new test
script.

Also, this approach of adding tests in a single commit makes it really
easy to miss testing some of the changes -- for example, I see no use of
backtrace anywhere in fetch_src_and_symbols.exp, so that patch isn't
being tested at all.

> +
>  # Write some assembly that just has a .gnu_debugaltlink section.
>  # Copied from testsuite/gdb.dwarf2/dwzbuildid.exp.
>  proc write_just_debugaltlink {filename dwzname buildid} {
> @@ -94,6 +111,7 @@ proc write_dwarf_file {filename buildid {value 99}} {
>  }
>  
>  set corefile [standard_output_file "corefile"]
> +set lazy_support -1
>  
>  # Setup the global variable DEBUGDIR as a directory containing the
>  # debug information for the test executable.
> @@ -103,6 +121,8 @@ set corefile [standard_output_file "corefile"]
>  # running.
>  proc_with_prefix no_url { } {
>      global binfile outputdir debugdir
> +    global sectexec lib_sl libfile lazy_support
> +    global gdb_prompt
>  
>      setenv DEBUGINFOD_URLS ""
>  
> @@ -119,11 +139,18 @@ proc_with_prefix no_url { } {
>  	return -1
>      }
>  
> +    if { [gdb_gnu_strip_debug $lib_sl ""] != 0} {
> +	fail "strip shlib debuginfo"
> +	return -1
> +    }
> +
>      set debugdir [standard_output_file "debug"]
>      set debuginfo [standard_output_file "fetch_src_and_symbols.debug"]
> +    set debuginfo_shlib [standard_output_file $libfile.sl.debug]
>  
>      file mkdir $debugdir
>      file rename -force $debuginfo $debugdir
> +    file rename -force $debuginfo_shlib $debugdir
>  
>      # Test that GDB cannot find symbols without debuginfod.
>      clean_restart $binfile
> @@ -171,6 +198,25 @@ proc_with_prefix no_url { } {
>  
>      clean_restart
>      gdb_test "core $::corefile" ".*in ?? ().*" "file [file tail $::corefile]"
> +    clean_restart
> +
> +    # Check for lazy downloading support.
> +    gdb_test_multiple "set debuginfod enabled lazy" "check for lazy" {
> +	-re ".*lazy downloading is not compiled into GDB.*\n.*${gdb_prompt} $" {
> +	    set lazy_support 0
> +	}
> +	-re ".*${gdb_prompt} $" {
> +	    set lazy_support 1
> +	}
> +    }

As one example, this would be a great candidate for moving into
lib/debuginfod-support.exp.

Thanks,
Andrew

> +
> +    if {$lazy_support == 1} {
> +	gdb_test "file $sectexec" "" "file [file tail $sectexec] file no url"
> +	gdb_test "start" "" "file [file tail $sectexec] start no url"
> +	gdb_test "info sharedlibrary" ".*Yes \\(\\*\\).*libsection.*" "lib no debug"
> +    } else {
> +	untested "lazy support no_url"
> +    }
>  }
>  
>  # Test that GDB prints the debuginfod URLs when loading files.  URLS
> @@ -208,6 +254,7 @@ proc disable_delete_breakpoints {} {
>  # expected debug information.
>  proc_with_prefix local_url { } {
>      global binfile outputdir debugdir db
> +    global sectexec lib_sl libfile lazy_support
>  
>      set url [start_debuginfod $db $debugdir]
>      if { $url == "" } {
> @@ -256,6 +303,17 @@ proc_with_prefix local_url { } {
>  	"file [file tail ${binfile}_alt.o]" \
>  	$enable_debuginfod_question "y"
>  
> +    if {$lazy_support == 1} {
> +	# GDB should now download .gdb_index.
> +	clean_restart
> +	gdb_test "set debuginfod enabled lazy" "" "set lazy urls"
> +	gdb_test "file $sectexec" "" "file [file tail $sectexec] file urls"
> +	set res ".*Download.*\.gdb_index.*libsection.*\r\nDownload.*debug info.*libsection.*"
> +	gdb_test "start $sectexec" $res "file [file tail $sectexec] start urls"
> +    } else {
> +	untested "lazy support urls"
> +    }
> +
>      # Configure debuginfod with commands.
>      unsetenv DEBUGINFOD_URLS
>      clean_restart
> diff --git a/gdb/testsuite/gdb.debuginfod/libsection.c b/gdb/testsuite/gdb.debuginfod/libsection.c
> new file mode 100644
> index 00000000000..510f9205282
> --- /dev/null
> +++ b/gdb/testsuite/gdb.debuginfod/libsection.c
> @@ -0,0 +1,24 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2020-2023 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 <stdio.h>
> +
> +void
> +libsection_test ()
> +{
> +  printf ("In libsection\n");
> +}
> diff --git a/gdb/testsuite/gdb.debuginfod/section.c b/gdb/testsuite/gdb.debuginfod/section.c
> new file mode 100644
> index 00000000000..3598896c1bc
> --- /dev/null
> +++ b/gdb/testsuite/gdb.debuginfod/section.c
> @@ -0,0 +1,28 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2020-2023 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 <fcntl.h>
> +
> +extern void libsection_test ();
> +
> +int
> +main()
> +{
> +  (void) open ("", 0);
> +  libsection_test ();
> +  return 0;
> +}
> -- 
> 2.39.2
  

Patch

diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
index 8158c5c3cc6..fc7e4b685dc 100644
--- a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
+++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
@@ -42,6 +42,23 @@  if { [gdb_compile "$sourcetmp" "${binfile}2" executable {debug build-id}] != ""
     return -1
 }
 
+set sectfile "section"
+set sectsrc $srcdir/$subdir/section.c
+set sectexec [standard_output_file $sectfile]
+
+set libfile "libsection"
+set libsrc $srcdir/$subdir/$libfile.c
+set lib_sl [standard_output_file $libfile.sl]
+
+set lib_opts [list debug build-id ]
+set exec_opts [list debug build-id shlib=$lib_sl]
+
+if { [gdb_compile_shlib $libsrc $lib_sl $lib_opts] != ""
+     || [gdb_compile $sectsrc $sectexec executable $exec_opts] != "" } {
+    untested "failed to compile"
+    return -1
+}
+
 # Write some assembly that just has a .gnu_debugaltlink section.
 # Copied from testsuite/gdb.dwarf2/dwzbuildid.exp.
 proc write_just_debugaltlink {filename dwzname buildid} {
@@ -94,6 +111,7 @@  proc write_dwarf_file {filename buildid {value 99}} {
 }
 
 set corefile [standard_output_file "corefile"]
+set lazy_support -1
 
 # Setup the global variable DEBUGDIR as a directory containing the
 # debug information for the test executable.
@@ -103,6 +121,8 @@  set corefile [standard_output_file "corefile"]
 # running.
 proc_with_prefix no_url { } {
     global binfile outputdir debugdir
+    global sectexec lib_sl libfile lazy_support
+    global gdb_prompt
 
     setenv DEBUGINFOD_URLS ""
 
@@ -119,11 +139,18 @@  proc_with_prefix no_url { } {
 	return -1
     }
 
+    if { [gdb_gnu_strip_debug $lib_sl ""] != 0} {
+	fail "strip shlib debuginfo"
+	return -1
+    }
+
     set debugdir [standard_output_file "debug"]
     set debuginfo [standard_output_file "fetch_src_and_symbols.debug"]
+    set debuginfo_shlib [standard_output_file $libfile.sl.debug]
 
     file mkdir $debugdir
     file rename -force $debuginfo $debugdir
+    file rename -force $debuginfo_shlib $debugdir
 
     # Test that GDB cannot find symbols without debuginfod.
     clean_restart $binfile
@@ -171,6 +198,25 @@  proc_with_prefix no_url { } {
 
     clean_restart
     gdb_test "core $::corefile" ".*in ?? ().*" "file [file tail $::corefile]"
+    clean_restart
+
+    # Check for lazy downloading support.
+    gdb_test_multiple "set debuginfod enabled lazy" "check for lazy" {
+	-re ".*lazy downloading is not compiled into GDB.*\n.*${gdb_prompt} $" {
+	    set lazy_support 0
+	}
+	-re ".*${gdb_prompt} $" {
+	    set lazy_support 1
+	}
+    }
+
+    if {$lazy_support == 1} {
+	gdb_test "file $sectexec" "" "file [file tail $sectexec] file no url"
+	gdb_test "start" "" "file [file tail $sectexec] start no url"
+	gdb_test "info sharedlibrary" ".*Yes \\(\\*\\).*libsection.*" "lib no debug"
+    } else {
+	untested "lazy support no_url"
+    }
 }
 
 # Test that GDB prints the debuginfod URLs when loading files.  URLS
@@ -208,6 +254,7 @@  proc disable_delete_breakpoints {} {
 # expected debug information.
 proc_with_prefix local_url { } {
     global binfile outputdir debugdir db
+    global sectexec lib_sl libfile lazy_support
 
     set url [start_debuginfod $db $debugdir]
     if { $url == "" } {
@@ -256,6 +303,17 @@  proc_with_prefix local_url { } {
 	"file [file tail ${binfile}_alt.o]" \
 	$enable_debuginfod_question "y"
 
+    if {$lazy_support == 1} {
+	# GDB should now download .gdb_index.
+	clean_restart
+	gdb_test "set debuginfod enabled lazy" "" "set lazy urls"
+	gdb_test "file $sectexec" "" "file [file tail $sectexec] file urls"
+	set res ".*Download.*\.gdb_index.*libsection.*\r\nDownload.*debug info.*libsection.*"
+	gdb_test "start $sectexec" $res "file [file tail $sectexec] start urls"
+    } else {
+	untested "lazy support urls"
+    }
+
     # Configure debuginfod with commands.
     unsetenv DEBUGINFOD_URLS
     clean_restart
diff --git a/gdb/testsuite/gdb.debuginfod/libsection.c b/gdb/testsuite/gdb.debuginfod/libsection.c
new file mode 100644
index 00000000000..510f9205282
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/libsection.c
@@ -0,0 +1,24 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020-2023 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 <stdio.h>
+
+void
+libsection_test ()
+{
+  printf ("In libsection\n");
+}
diff --git a/gdb/testsuite/gdb.debuginfod/section.c b/gdb/testsuite/gdb.debuginfod/section.c
new file mode 100644
index 00000000000..3598896c1bc
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/section.c
@@ -0,0 +1,28 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2020-2023 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 <fcntl.h>
+
+extern void libsection_test ();
+
+int
+main()
+{
+  (void) open ("", 0);
+  libsection_test ();
+  return 0;
+}