diff --git a/gdb/build-id.c b/gdb/build-id.c
index 0c5d65d02ac..4c6e44560f0 100644
--- a/gdb/build-id.c
+++ b/gdb/build-id.c
@@ -202,7 +202,8 @@ build_id_to_exec_bfd (size_t build_id_len, const bfd_byte *build_id)
 /* See build-id.h.  */
 
 std::string
-find_separate_debug_file_by_buildid (struct objfile *objfile)
+find_separate_debug_file_by_buildid (struct objfile *objfile,
+				     std::vector<std::string> *warnings_vector)
 {
   const struct bfd_build_id *build_id;
 
@@ -220,8 +221,10 @@ find_separate_debug_file_by_buildid (struct objfile *objfile)
       if (abfd != NULL
 	  && filename_cmp (bfd_get_filename (abfd.get ()),
 			   objfile_name (objfile)) == 0)
-	warning (_("\"%s\": separate debug info file has no debug info"),
-		 bfd_get_filename (abfd.get ()));
+	warnings_vector->emplace_back
+	  (string_printf
+	   (_("\"%s\": separate debug info file has no debug info"),
+	    bfd_get_filename (abfd.get ())));
       else if (abfd != NULL)
 	return std::string (bfd_get_filename (abfd.get ()));
     }
diff --git a/gdb/build-id.h b/gdb/build-id.h
index 7629427c504..5d5c21845f2 100644
--- a/gdb/build-id.h
+++ b/gdb/build-id.h
@@ -49,10 +49,16 @@ extern gdb_bfd_ref_ptr build_id_to_exec_bfd (size_t build_id_len,
 
 /* Find the separate debug file for OBJFILE, by using the build-id
    associated with OBJFILE's BFD.  If successful, returns the file name for the
-   separate debug file, otherwise, return an empty string.  */
+   separate debug file, otherwise, return an empty string.
+
+   Any warnings that are generated by the lookup process should be added to
+   WARNINGS_VECTOR, one std::string per warning.  If some other mechanism can
+   be used to lookup the debug information then the warning will not be shown,
+   however, if GDB fails to find suitable debug information using any
+   approach, then any warnings will be printed.  */
 
 extern std::string find_separate_debug_file_by_buildid
-  (struct objfile *objfile);
+  (struct objfile *objfile, std::vector<std::string> *warnings_vector);
 
 /* Return an hex-string representation of BUILD_ID.  */
 
diff --git a/gdb/coffread.c b/gdb/coffread.c
index f29627d9797..6377b08d246 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -734,10 +734,13 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
   /* Try to add separate debug file if no symbols table found.   */
   if (!objfile->has_partial_symbols ())
     {
-      std::string debugfile = find_separate_debug_file_by_buildid (objfile);
+      std::vector<std::string> warnings_vector;
+      std::string debugfile
+	= find_separate_debug_file_by_buildid (objfile, &warnings_vector);
 
       if (debugfile.empty ())
-	debugfile = find_separate_debug_file_by_debuglink (objfile);
+	debugfile
+	  = find_separate_debug_file_by_debuglink (objfile, &warnings_vector);
 
       if (!debugfile.empty ())
 	{
@@ -746,6 +749,11 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 	  symbol_file_add_separate (debug_bfd, debugfile.c_str (),
 				    symfile_flags, objfile);
 	}
+      /* If all the methods to collect the debuginfo failed, print any
+	 warnings that were collected.  */
+      if (debugfile.empty () && !warnings_vector.empty ())
+	for (const std::string &w : warnings_vector)
+	  warning ("%s", w.c_str ());
     }
 }
 
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 64aeb239670..ae159408faf 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -1194,6 +1194,7 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
 			 symfile_add_flags symfile_flags)
 {
   bool has_dwarf2 = true;
+  std::vector<std::string> warnings_vector;
 
   if (dwarf2_has_info (objfile, NULL, true))
     dwarf2_initialize_objfile (objfile);
@@ -1213,10 +1214,12 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
 	   && objfile->separate_debug_objfile == NULL
 	   && objfile->separate_debug_objfile_backlink == NULL)
     {
-      std::string debugfile = find_separate_debug_file_by_buildid (objfile);
+      std::string debugfile
+	= find_separate_debug_file_by_buildid (objfile, &warnings_vector);
 
       if (debugfile.empty ())
-	debugfile = find_separate_debug_file_by_debuglink (objfile);
+	debugfile = find_separate_debug_file_by_debuglink (objfile,
+							   &warnings_vector);
 
       if (!debugfile.empty ())
 	{
@@ -1258,6 +1261,11 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
 		}
 	    }
 	}
+      /* If all the methods to collect the debuginfo failed, print
+	 the warnings, if there're any. */
+      if (debugfile.empty () && !has_dwarf2 && !warnings_vector.empty ())
+	for (const std::string &w : warnings_vector)
+	  warning ("%s", w.c_str ());
     }
 
   return has_dwarf2;
diff --git a/gdb/symfile.c b/gdb/symfile.c
index eb27668f9d3..9d63d80e100 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1244,7 +1244,8 @@ bool separate_debug_file_debug = false;
 
 static int
 separate_debug_file_exists (const std::string &name, unsigned long crc,
-			    struct objfile *parent_objfile)
+			    struct objfile *parent_objfile,
+			    std::vector<std::string> *warnings_vector)
 {
   unsigned long file_crc;
   int file_crc_p;
@@ -1336,9 +1337,10 @@ separate_debug_file_exists (const std::string &name, unsigned long crc,
 	}
 
       if (verified_as_different || parent_crc != file_crc)
-	warning (_("the debug information found in \"%s\""
-		   " does not match \"%s\" (CRC mismatch).\n"),
-		 name.c_str (), objfile_name (parent_objfile));
+	warnings_vector->emplace_back
+	  (string_printf (_("the debug information found in \"%s\""
+			    " does not match \"%s\" (CRC mismatch).\n"),
+			  name.c_str (), objfile_name (parent_objfile)));
 
       if (separate_debug_file_debug)
 	gdb_printf (gdb_stdlog, _(" no, CRC doesn't match.\n"));
@@ -1373,13 +1375,17 @@ show_debug_file_directory (struct ui_file *file, int from_tty,
    looking for.  CANON_DIR is the "realpath" form of DIR.
    DIR must contain a trailing '/'.
    Returns the path of the file with separate debug info, or an empty
-   string.  */
+   string.
+
+   Any warnings generated as part of the lookup process are added to
+   WARNINGS_VECTOR, one std::string per warning.  */
 
 static std::string
 find_separate_debug_file (const char *dir,
 			  const char *canon_dir,
 			  const char *debuglink,
-			  unsigned long crc32, struct objfile *objfile)
+			  unsigned long crc32, struct objfile *objfile,
+			  std::vector<std::string> *warnings_vector)
 {
   if (separate_debug_file_debug)
     gdb_printf (gdb_stdlog,
@@ -1390,7 +1396,7 @@ find_separate_debug_file (const char *dir,
   std::string debugfile = dir;
   debugfile += debuglink;
 
-  if (separate_debug_file_exists (debugfile, crc32, objfile))
+  if (separate_debug_file_exists (debugfile, crc32, objfile, warnings_vector))
     return debugfile;
 
   /* Then try in the subdirectory named DEBUG_SUBDIRECTORY.  */
@@ -1399,7 +1405,7 @@ find_separate_debug_file (const char *dir,
   debugfile += "/";
   debugfile += debuglink;
 
-  if (separate_debug_file_exists (debugfile, crc32, objfile))
+  if (separate_debug_file_exists (debugfile, crc32, objfile, warnings_vector))
     return debugfile;
 
   /* Then try in the global debugfile directories.
@@ -1444,7 +1450,8 @@ find_separate_debug_file (const char *dir,
       debugfile += dir_notarget;
       debugfile += debuglink;
 
-      if (separate_debug_file_exists (debugfile, crc32, objfile))
+      if (separate_debug_file_exists (debugfile, crc32, objfile,
+				      warnings_vector))
 	return debugfile;
 
       const char *base_path = NULL;
@@ -1466,7 +1473,8 @@ find_separate_debug_file (const char *dir,
 	  debugfile += "/";
 	  debugfile += debuglink;
 
-	  if (separate_debug_file_exists (debugfile, crc32, objfile))
+	  if (separate_debug_file_exists (debugfile, crc32, objfile,
+					  warnings_vector))
 	    return debugfile;
 
 	  /* If the file is in the sysroot, try using its base path in
@@ -1479,7 +1487,8 @@ find_separate_debug_file (const char *dir,
 	  debugfile += "/";
 	  debugfile += debuglink;
 
-	  if (separate_debug_file_exists (debugfile, crc32, objfile))
+	  if (separate_debug_file_exists (debugfile, crc32, objfile,
+					  warnings_vector))
 	    return debugfile;
 	}
 
@@ -1507,11 +1516,11 @@ terminate_after_last_dir_separator (char *path)
   path[i + 1] = '\0';
 }
 
-/* Find separate debuginfo for OBJFILE (using .gnu_debuglink section).
-   Returns pathname, or an empty string.  */
+/* See symtab.h.  */
 
 std::string
-find_separate_debug_file_by_debuglink (struct objfile *objfile)
+find_separate_debug_file_by_debuglink
+  (struct objfile *objfile, std::vector<std::string> *warnings_vector)
 {
   unsigned long crc32;
 
@@ -1531,7 +1540,8 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
 
   std::string debugfile
     = find_separate_debug_file (dir.c_str (), canon_dir.get (),
-				debuglink.get (), crc32, objfile);
+				debuglink.get (), crc32, objfile,
+				warnings_vector);
 
   if (debugfile.empty ())
     {
@@ -1555,7 +1565,8 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
 							symlink_dir.get (),
 							debuglink.get (),
 							crc32,
-							objfile);
+							objfile,
+							warnings_vector);
 		}
 	    }
 	}
diff --git a/gdb/symfile.h b/gdb/symfile.h
index ffd1acddfdb..e21c08ce027 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -241,7 +241,14 @@ extern struct objfile *symbol_file_add_from_bfd (const gdb_bfd_ref_ptr &,
 extern void symbol_file_add_separate (const gdb_bfd_ref_ptr &, const char *,
 				      symfile_add_flags, struct objfile *);
 
-extern std::string find_separate_debug_file_by_debuglink (struct objfile *);
+/* Find separate debuginfo for OBJFILE (using .gnu_debuglink section).
+   Returns pathname, or an empty string.
+
+   Any warnings generated as part of this lookup are added to
+   WARNINGS_VECTOR, one std::string per warning.  */
+
+extern std::string find_separate_debug_file_by_debuglink
+  (struct objfile *objfile, std::vector<std::string> *warnings_vector);
 
 /* Build (allocate and populate) a section_addr_info struct from an
    existing section table.  */
diff --git a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.c b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.c
new file mode 100644
index 00000000000..223a703bb4f
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.c
@@ -0,0 +1,20 @@
+/* Copyright 2022 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/>.  */
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
new file mode 100644
index 00000000000..b328e19f438
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
@@ -0,0 +1,142 @@
+# Copyright 2022 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/>.
+#
+# This test triggers the "separate debug info file has no debug info" warning by replacing
+# the build-id based .debug file with the stripped binary and then loading it to gdb.
+# It then also sets up local debuginfod server with the correct debug file to download
+# to make sure no warnings are emmitted.
+
+
+standard_testfile
+
+load_lib debuginfod-support.exp
+
+if { [skip_debuginfod_tests] } { return -1 }
+
+if {[build_executable "build executable" ${testfile} ${srcfile} \
+	 {debug build-id}] == -1} {
+    return -1
+}
+
+# Split BINFILE into BINFILE.stripped and BINFILE.debug, the first is
+# the executable with the debug information removed, and the second is
+# the debug information.
+#
+# However, by passing the "no-debuglink" flag we prevent this proc
+# from adding a .gnu_debuglink section to the executable.  Any lookup
+# of the debug information by GDB will need to be done based on the
+# build-id.
+if [gdb_gnu_strip_debug $binfile no-debuglink] {
+    unsupported "cannot produce separate debug info files"
+    return -1
+}
+
+# Get the .build-id/PREFIX/SUFFIX.debug file name, and convert it to
+# an absolute path, this is where we will place the debug information.
+set build_id_debug_file \
+    [standard_output_file [build_id_debug_filename_get $binfile]]
+
+# Get the BINFILE.debug filename.  This is the file we should be
+# moving to the BUILD_ID_DEBUG_FILE location, but we wont, we're going
+# to move something else there instead.
+set debugfile [standard_output_file "${binfile}.debug"]
+
+# Move debugfile to the directory to be used by the debuginfod
+# server.
+set debuginfod_debugdir [standard_output_file "debug"]
+remote_exec build "mkdir $debuginfod_debugdir"
+remote_exec build "mv $debugfile $debuginfod_debugdir"
+
+# This is BINFILE with the debug information removed.  We are going to
+# place this in the BUILD_ID_DEBUG_FILE location, this would usually
+# represent a mistake by the user, and will trigger a warning from
+# GDB, this is the warning we are checking for.
+set stripped_binfile [standard_output_file "${binfile}.stripped"]
+
+# Create the .build-id/PREFIX directory name from
+# .build-id/PREFIX/SUFFIX.debug filename.
+set debugdir [file dirname ${build_id_debug_file}]
+remote_exec build "mkdir -p $debugdir"
+
+# Now move the stripped executable into the .build-id directory
+# instead of the debug information.  Later on we're going to try and
+# load this into GDB.  GDB will then try to find the separate debug
+# information, which will point back at this file, which also doesn't
+# have debug information, which could cause a loop.  But GDB will spot
+# this and give a warning.
+remote_exec build "mv ${stripped_binfile} ${build_id_debug_file}"
+
+# Now start GDB.
+clean_restart
+
+# Tell GDB where to look for the .build-id directory.
+set debug_file_directory [standard_output_file ""]
+gdb_test_no_output "set debug-file-directory ${debug_file_directory}" \
+    "set debug-file-directory"
+
+# Now load the file into GDB, and look for the warning.
+gdb_test "file ${build_id_debug_file}" \
+    [multi_line \
+    ".*Reading symbols from.*debuginfo.*" \
+    ".*separate debug info file has no debug info.*"] \
+    "load test file, expect a warning"
+
+# Now we should close GDB.
+gdb_exit
+
+# Create CACHE and DB directories ready for debuginfod to use.
+prepare_for_debuginfod cache db
+
+# Start debuginfod server and test debuginfo is downloaded from
+# it and we can se no warnings anymore.
+proc_with_prefix local_debuginfod { } {
+    global db debuginfod_debugdir cache build_id_debug_file
+
+    set url [start_debuginfod $db $debuginfod_debugdir]
+    if { $url == "" } {
+	unresolved "failed to start debuginfod server"
+	return
+    }
+
+    # Point the client to the server.
+    setenv DEBUGINFOD_URLS $url
+
+    # GDB should now find the symbol and source files.
+    clean_restart
+
+    # Enable debuginfod and fetch the debuginfo.
+    gdb_test_no_output "set debuginfod enabled on"
+
+    # "separate debug info file has no debug info" warning should not be
+    # reported now because the correct debuginfo should be fetched from
+    # debuginfod.
+    gdb_test "file ${build_id_debug_file}" \
+	[multi_line \
+	     "Reading symbols from ${build_id_debug_file}\\.\\.\\." \
+	     "Downloading separate debug info for ${build_id_debug_file}\\.\\.\\." \
+	     "Reading symbols from ${cache}/\[^\r\n\]+\\.\\.\\.(?:\r\nExpanding full symbols from \[^\r\n\]+)*"] \
+	"debuginfod running, info downloaded, no warnings"
+}
+
+# Restart GDB, and load the file, this time we should correctly get
+# the debug symbols from the server, and should not see the warning.
+with_debuginfod_env $cache {
+    local_debuginfod
+}
+
+stop_debuginfod
+# Spare debug files may confuse testsuite runs in the future.
+remote_exec build "rm -f $debugfile"
+
diff --git a/gdb/testsuite/gdb.debuginfod/crc_mismatch-2.c b/gdb/testsuite/gdb.debuginfod/crc_mismatch-2.c
new file mode 100644
index 00000000000..6b3984dc7d2
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/crc_mismatch-2.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2022 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/>.  */
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.debuginfod/crc_mismatch.c b/gdb/testsuite/gdb.debuginfod/crc_mismatch.c
new file mode 100644
index 00000000000..1801a9c953a
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/crc_mismatch.c
@@ -0,0 +1,20 @@
+/* Copyright 2022 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/>.  */
+
+int
+main (int argc, char **argv, char **envp)
+{
+  return argc;
+}
diff --git a/gdb/testsuite/gdb.debuginfod/crc_mismatch.exp b/gdb/testsuite/gdb.debuginfod/crc_mismatch.exp
new file mode 100644
index 00000000000..76cc771814b
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/crc_mismatch.exp
@@ -0,0 +1,114 @@
+# Copyright 2022 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/>.
+#
+# This test compiles two executables: crc_mismatch and crc_mismatch-2
+# and then strips them of debuginfo creating separate debug files. The test
+# then replaces crc_mismatch-2.debug with crc_mismatch.debug to trigger
+# "CRC mismatch" warning. A local debuginfod server is setup to supply
+# the correct debug file, now when GDB looks up the debug info no warning
+# is given.
+
+standard_testfile .c -2.c
+
+load_lib debuginfod-support.exp
+
+if { [skip_debuginfod_tests] } { return -1 }
+
+if  {[build_executable "build executable" $testfile $srcfile debug] == -1 } {
+    untested "failed to compile"
+    return -1
+}
+
+# The procedure gdb_gnu_strip_debug will produce an executable called
+# ${binfile}, which is just like the executable ($binfile) but without
+# the debuginfo. Instead $binfile has a .gnu_debuglink section which
+# contains the name of a debuginfo only file.
+if [gdb_gnu_strip_debug $binfile] {
+    # Check that you have a recent version of strip and objcopy installed.
+    unsupported "cannot produce separate debug info files"
+    return -1
+}
+
+set debugfile "$[standard_output_file ${testfile}.debug]"
+set debugdir [standard_output_file "debug"]
+remote_exec build "mkdir $debugdir"
+remote_exec build "mkdir -p [file dirname $debugfile]"
+remote_exec build "mv -f [standard_output_file ${testfile}.debug] $debugfile"
+
+# Test CRC mismatch is reported.
+if {[build_executable crc_mismatch.exp crc_mismatch-2 crc_mismatch-2.c debug] != -1
+    && ![gdb_gnu_strip_debug [standard_output_file crc_mismatch-2]]} {
+
+    # Copy the correct debug file for crc_mismatch-2 to the debugdir
+    # which is going to be used by local debuginfod.
+    remote_exec build "cp [standard_output_file crc_mismatch-2.debug] ${debugdir}"
+    # Move the unmatching debug file for crc_mismatch-2 instead of its real one
+    # to trigger the "CRC mismatch" warning.
+    remote_exec build "mv ${debugfile} [standard_output_file crc_mismatch-2.debug]"
+
+    gdb_exit
+    gdb_start
+
+    set escapedobjdirsubdir [string_to_regexp [standard_output_file {}]]
+
+    gdb_test "file [standard_output_file crc_mismatch-2]" "warning: the debug information found in \"${escapedobjdirsubdir}/crc_mismatch-2\\.debug\" does not match \"${escapedobjdirsubdir}/crc_mismatch-2\" \\(CRC mismatch\\)\\..*\\(No debugging symbols found in .*\\).*" "CRC mismatch is reported"
+}
+
+# Create CACHE and DB directories ready for debuginfod to use.
+prepare_for_debuginfod cache db
+
+# Start debuginfod server, test the correct debuginfo was fetched
+# from the server so there're not warnings anymore.
+proc_with_prefix local_debuginfod { } {
+    global binfile db debugdir cache
+    set escapedobjdirsubdir [string_to_regexp [standard_output_file {}]]
+
+    set url [start_debuginfod $db $debugdir]
+    if { $url == "" } {
+	unresolved "failed to start debuginfod server"
+	return
+    }
+
+    # Point the client to the server.
+    setenv DEBUGINFOD_URLS $url
+
+    # GDB should now find the symbol and source files.
+    clean_restart
+
+    # Enable debuginfod and fetch the debuginfo.
+    gdb_test_no_output "set debuginfod enabled on"
+    gdb_test "file $binfile" ".*Reading symbols from.*debuginfo.*" \
+	"file [file tail $binfile] cmd on"
+
+    # CRC mismatch should not be reported now because the correct debuginfo
+    # should be fetched from debuginfod.
+    gdb_test "file [standard_output_file crc_mismatch-2]" \
+	[multi_line \
+	     "Reading symbols from ${escapedobjdirsubdir}/crc_mismatch-2\\.\\.\\." \
+	     "Downloading separate debug info for ${escapedobjdirsubdir}/crc_mismatch-2\\.\\.\\." \
+	     "Reading symbols from ${cache}/\[^\r\n\]+\\.\\.\\.(?:\r\nExpanding full symbols from \[^\r\n\]+)*"] \
+	 "debuginfod running, info downloaded, no CRC mismatch"
+
+    #
+
+}
+
+with_debuginfod_env $cache {
+    local_debuginfod
+}
+
+stop_debuginfod
+# Spare debug files may confuse testsuite runs in the future.
+remote_exec build "rm -f $debugfile"
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 008f59b9f30..34c0d1a4e02 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -7153,9 +7153,19 @@ proc build_id_debug_filename_get { filename } {
     return ".build-id/${data}.debug"
 }
 
-# Create stripped files for DEST, replacing it.  If ARGS is passed, it is a
-# list of optional flags.  The only currently supported flag is no-main,
-# which removes the symbol entry for main from the separate debug file.
+# DEST should be a file compiled with debug information.  This proc
+# creates two new files DEST.debug which contains the debug
+# information extracted from DEST, and DEST.stripped, which is a copy
+# of DEST with the debug information removed.  A '.gnu_debuglink'
+# section will be added to DEST.stripped that points to DEST.debug.
+#
+# If ARGS is passed, it is a list of optional flags.  The currently
+# supported flags are:
+#
+#   - no-main : remove the symbol entry for main from the separate
+#               debug file DEST.debug,
+#   - no-debuglink : don't add the '.gnu_debuglink' section to
+#                    DEST.stripped.
 #
 # Function returns zero on success.  Function will return non-zero failure code
 # on some targets not supporting separate debug info (such as i386-msdos).
@@ -7200,7 +7210,7 @@ proc gdb_gnu_strip_debug { dest args } {
     # leaves the symtab in the original file only.  There's no way to get
     # objcopy or strip to remove the symbol table without also removing the
     # debugging sections, so this is as close as we can get.
-    if { [llength $args] == 1 && [lindex $args 0] == "no-main" } {
+    if {[lsearch -exact $args "no-main"] != -1} {
 	set result [catch "exec $objcopy_program -N main ${debug_file} ${debug_file}-tmp" output]
 	verbose "result is $result"
 	verbose "output is $output"
@@ -7211,15 +7221,17 @@ proc gdb_gnu_strip_debug { dest args } {
 	file rename "${debug_file}-tmp" "${debug_file}"
     }
 
-    # Link the two previous output files together, adding the .gnu_debuglink
-    # section to the stripped_file, containing a pointer to the debug_file,
-    # save the new file in dest.
-    # This will be the regular executable filename, in the usual location.
-    set result [catch "exec $objcopy_program --add-gnu-debuglink=${debug_file} ${stripped_file} ${dest}" output]
-    verbose "result is $result"
-    verbose "output is $output"
-    if {$result == 1} {
-      return 1
+    # Unless the "no-debuglink" flag is passed, then link the two
+    # previous output files together, adding the .gnu_debuglink
+    # section to the stripped_file, containing a pointer to the
+    # debug_file, save the new file in dest.
+    if {[lsearch -exact $args "no-debuglink"] == -1} {
+	set result [catch "exec $objcopy_program --add-gnu-debuglink=${debug_file} ${stripped_file} ${dest}" output]
+	verbose "result is $result"
+	verbose "output is $output"
+	if {$result == 1} {
+	    return 1
+	}
     }
 
     # Workaround PR binutils/10802:
