From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 6A5B1388C5C9 for ; Thu, 15 Dec 2022 15:57:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6A5B1388C5C9 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1671119827; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iTjSzbpXWRkNtbOulKKzXloMXe/FZzZGtLseE4TL5GM=; b=gQuQ/FEyMrt8n6LOQ8dnzdlPpazoi9MFYPLrsjscZ4X2cA/zkkJ7MmY3/sgL8DVn6mdajz MQP08RbqrbGZqf9obIgF4xr7M/4w/sMC6l64+7jZPw+bMybIHA1sZtbU3cM8IUaNTUJN7n MhPEokBvyKcnvRzTObZpLi3MmiDm+q0= Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-653-Pwui-CdKN1CRcYpWcMigdQ-1; Thu, 15 Dec 2022 10:57:06 -0500 X-MC-Unique: Pwui-CdKN1CRcYpWcMigdQ-1 Received: by mail-ej1-f69.google.com with SMTP id hd17-20020a170907969100b007c117851c81so14001580ejc.10 for ; Thu, 15 Dec 2022 07:57:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=iTjSzbpXWRkNtbOulKKzXloMXe/FZzZGtLseE4TL5GM=; b=yv60IOykPtWIK7d9s/JlAtGT/kpBcyvsgdxc8XTcTRwm09CRxLGs+aRe6Bxvkw6aFi bj9z0klNHaYlFHCD18+SZvfSQpzC9ZX2Qk6Bet38aF9al0XEblV+g8SkXK6fd+RYXA8j x3dk4bNHLT4sC4FN7c6nMeOwhYxcgYsMEp5eE6iiOrIfI57FTYa6zP/WC/NtE6gbEMA9 RrHHed9S7Ui7tDrlDqoB4I2Gy4WIYuv5C+uIeg6tnHRrVb7vKlOIFcqSwmBZC5fk03lB fo0TbigDpnBU2ts9ki4fL60iRdBsouT4YuMfdD3ZPiCg8zhfBd12d0ZTtMGCHfuixaoY iETQ== X-Gm-Message-State: ANoB5plmoiwhBpybxiqallt4wP976+jalUcVFBgg+dieZ1VVeWvl2rVJ P+Ociej23wFh9NDRA1EK2UHwiJmqyjusRtGrFVrA+Mp7Re0z8cDcbQORGjvCBQzDCjVbbADiQxL ZSfVoh+5gJtcculsMCBSddw== X-Received: by 2002:a17:906:c00b:b0:7c1:4ba1:70c6 with SMTP id e11-20020a170906c00b00b007c14ba170c6mr21030122ejz.77.1671119824925; Thu, 15 Dec 2022 07:57:04 -0800 (PST) X-Google-Smtp-Source: AA0mqf7totSb4jxRZP4JkKcBLS0i4lcYMZRVKuNHwlBjeCjh2i3Jz7h6dTgktVkmT32tJ1LjS1Cy4g== X-Received: by 2002:a17:906:c00b:b0:7c1:4ba1:70c6 with SMTP id e11-20020a170906c00b00b007c14ba170c6mr21030093ejz.77.1671119824412; Thu, 15 Dec 2022 07:57:04 -0800 (PST) Received: from [192.168.0.45] (ip-62-245-66-121.bb.vodafone.cz. [62.245.66.121]) by smtp.gmail.com with ESMTPSA id b10-20020a17090630ca00b0073dbaeb50f6sm7236309ejb.169.2022.12.15.07.57.03 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 15 Dec 2022 07:57:04 -0800 (PST) Message-ID: <1f17c4f1-841f-eb97-cbac-3f0380ba9bc4@redhat.com> Date: Thu, 15 Dec 2022 16:57:03 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.5.1 Subject: Re: [PATCH] gdb: defer warnings when loading separate debug files To: ahajkova@redhat.com, gdb-patches@sourceware.org References: <20221212121535.4013497-1-ahajkova@redhat.com> From: Bruno Larsen In-Reply-To: <20221212121535.4013497-1-ahajkova@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,NICE_REPLY_A,RCVD_IN_BARRACUDACENTRAL,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 12/12/2022 13:15, AlexandraH á jkov á ahajkova--- via Gdb-patches wrote: > From: Alexandra Hájková > > 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. Hello Sasha, I am not very familiar with the area of the code, but I see no issues with it and it introduces no regressions, so: Reviewed-By: Bruno Larsen -- Cheers, Bruno > --- > gdb/build-id.c | 9 +- > gdb/build-id.h | 10 +- > gdb/coffread.c | 12 +- > gdb/elfread.c | 12 +- > gdb/symfile.c | 43 ++++-- > 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, 412 insertions(+), 39 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 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 *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 *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 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 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 *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 *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 *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 *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 . */ > + > +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 . > +# > +# 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 . */ > + > +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 . */ > + > +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 . > +# > +# 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: