From: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
To: gdb-patches@sourceware.org
Subject: Re: [PATCH v2] gdb: defer warnings when loading separate debug files
Date: Thu, 19 Jan 2023 12:21:35 +0100 [thread overview]
Message-ID: <CAJVr-EOQnJ9ay_e+JACLsKMFP1uFuCy7WkqUnz7Oavii-r+2pg@mail.gmail.com> (raw)
In-Reply-To: <CAJVr-EM7A6KFzt02RMubE+ONcDFNJ4M-rWyuW7RoW4XJuyr-eQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 36578 bytes --]
Ping
On Mon, Jan 9, 2023 at 1:56 PM Alexandra Petlanova Hajkova <
ahajkova@redhat.com> wrote:
> Ping
>
> On Tue, Jan 3, 2023 at 2:04 PM <AlexandraHájková@sourceware.org> wrote:
>
>> From: Alexandra Hájková <ahajkova@redhat.com>
>>
>> Currently, when GDB loads debug information from a separate debug file,
>> there are a couple of warnings that could be produced if things go
>> wrong.
>>
>> In find_separate_debug_file_by_buildid (build-id.c) GDB can give a
>> warning if the separate debug file doesn't include any actual debug
>> information, and in separate_debug_file_exists (symfile.c) we can warn
>> if the CRC checksum in the separate debug file doesn't match the
>> checksum in the original executable.
>>
>> The problem here is that, when looking up debug information, GDB will
>> try several different approaches, lookup by build-id, lookup by
>> debug-link, and then a lookup from debuginfod. GDB can potentially give
>> a warning from an earlier attempt, and then succeed with a later
>> attempt. In the cases I have run into this is primarily a warning about
>> some out of date debug information on my machine, but then GDB finds the
>> correct information using debuginfod. This can be confusing to a user,
>> they will see warnings from GDB when really everything is working just
>> fine.
>>
>> For example:
>> warning: the debug information found in
>> "/usr/lib/debug//lib64/ld-2.32.so.debug"
>> does not match "/lib64/ld-linux-x86-64.so.2" (CRC mismatch).
>>
>> This diagnostic was printed on Fedora 33 even when the correct debuginfo
>> was downloaded.
>>
>> In this patch I propose that we defer any warnings related to looking up
>> debug information from a separate debug file. If any of the approaches
>> are successful then GDB will not print any of the warnings. As far as
>> the user is concerned, everything "just worked". Only if GDB completely
>> fails to find any suitable debug information will the warnings be
>> printed.
>>
>> The crc_mismatch 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.
>>
>> The build-id-no-debug-warning.exp is similar to the previous test. It
>> 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.
>> ---
>> Version 2 addresses Simon's concern advanced users/developers wants to be
>> notified
>> about problems along the way even if gdb fetches the correct debuginfo
>> eventually.
>> Print the warning immediatly if separate_debug_file_debug is set.
>>
>> gdb/build-id.c | 16 +-
>> gdb/build-id.h | 10 +-
>> gdb/coffread.c | 12 +-
>> gdb/elfread.c | 12 +-
>> gdb/symfile.c | 59 +++++---
>> gdb/symfile.h | 9 +-
>> .../build-id-no-debug-warning.c | 20 +++
>> .../build-id-no-debug-warning.exp | 142 ++++++++++++++++++
>> gdb/testsuite/gdb.debuginfod/crc_mismatch-2.c | 22 +++
>> gdb/testsuite/gdb.debuginfod/crc_mismatch.c | 20 +++
>> gdb/testsuite/gdb.debuginfod/crc_mismatch.exp | 114 ++++++++++++++
>> gdb/testsuite/lib/gdb.exp | 38 +++--
>> 12 files changed, 427 insertions(+), 47 deletions(-)
>> create mode 100644
>> gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.c
>> create mode 100644
>> gdb/testsuite/gdb.debuginfod/build-id-no-debug-warning.exp
>> create mode 100644 gdb/testsuite/gdb.debuginfod/crc_mismatch-2.c
>> create mode 100644 gdb/testsuite/gdb.debuginfod/crc_mismatch.c
>> create mode 100644 gdb/testsuite/gdb.debuginfod/crc_mismatch.exp
>>
>> diff --git a/gdb/build-id.c b/gdb/build-id.c
>> index c82f96402c8..f13ef52eaf3 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;
>>
>> @@ -219,9 +220,16 @@ find_separate_debug_file_by_buildid (struct objfile
>> *objfile)
>> /* Prevent looping on a stripped .debug file. */
>> 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 ()));
>> + objfile_name (objfile)) == 0) {
>> + if (separate_debug_file_debug)
>> + gdb_printf (gdb_stdlog,
>> + (_( "\"%s\": separate debug info file has no
>> debug info"),
>> + bfd_get_filename (abfd.get ())));
>> + else 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 4c3f8e0479a..191720ddf28 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 4950a7324c8..8f2a8673e10 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 ceaf81f0fca..0f6b64b0768 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 e0942dfb22d..58016b7d3f8 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;
>> @@ -1335,13 +1336,16 @@ 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));
>> -
>> - if (separate_debug_file_debug)
>> - gdb_printf (gdb_stdlog, _(" no, CRC doesn't match.\n"));
>> + if (verified_as_different || parent_crc != file_crc) {
>> + if (separate_debug_file_debug)
>> + gdb_printf (gdb_stdlog, _("the debug information found in
>> \"%s\""
>> + " does not match \"%s\" (CRC
>> mismatch).\n"),
>> + name.c_str (), objfile_name
>> (parent_objfile));
>> + else 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)));
>> + }
>>
>> return 0;
>> }
>> @@ -1373,13 +1377,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 +1398,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 +1407,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 +1452,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 +1475,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
>> @@ -1492,10 +1502,11 @@ find_separate_debug_file (const char *dir,
>> debugfile += "/";
>> debugfile += debuglink;
>>
>> - if (separate_debug_file_exists (debugfile, crc32, objfile))
>> - return debugfile;
>> - }
>> - }
>> + if (separate_debug_file_exists (debugfile, crc32, objfile,
>> + warnings_vector))
>> + return debugfile;
>> + }
>> + }
>> }
>>
>> return std::string ();
>> @@ -1520,11 +1531,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;
>>
>> @@ -1544,7 +1555,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 ())
>> {
>> @@ -1568,7 +1580,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 fb5fda795e3..b4d9a10e711 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 f94ec1b77f3..82bbf7513c4 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:
>> --
>> 2.38.1
>>
>>
next prev parent reply other threads:[~2023-01-19 11:21 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-03 13:03
2023-01-09 12:56 ` Alexandra Petlanova Hajkova
2023-01-19 11:21 ` Alexandra Petlanova Hajkova [this message]
2023-01-19 11:38 ` Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAJVr-EOQnJ9ay_e+JACLsKMFP1uFuCy7WkqUnz7Oavii-r+2pg@mail.gmail.com \
--to=ahajkova@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).