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.133.124]) by sourceware.org (Postfix) with ESMTPS id 2754B3858C52 for ; Thu, 19 Jan 2023 11:21:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2754B3858C52 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=1674127311; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=kqAYt+9ThSEnw2lFToui7OiGDTOD6LrycF2103UGuq0=; b=Rqe0Vhy6O+qWQwUqzKRSiCMf6+VrUs5Zd/nZS/RIo4iv87fN9rs15bRtGRrI5g6g0C7ogG Hdqd65OlYHmGZRA7EBrd5kpZjTPe5vWdtdlXxiaZdyN94qAFaJuAPTNiQFdJXBGjppioBL MosqkxsmWKWXgJoc40W40O7gel6lkSo= Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-190-QRlnxiRtNSS-wPC8d0lmuA-1; Thu, 19 Jan 2023 06:21:50 -0500 X-MC-Unique: QRlnxiRtNSS-wPC8d0lmuA-1 Received: by mail-pf1-f198.google.com with SMTP id j1-20020aa78001000000b0057d28e11cb6so805262pfi.11 for ; Thu, 19 Jan 2023 03:21:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kqAYt+9ThSEnw2lFToui7OiGDTOD6LrycF2103UGuq0=; b=NMGm/NKPs176lWBiD/kCL1MYRdUf4sA/IsWYWsdvgCt5ZUBFawHb2iPWlyia2QtOsR 5r+j3qVKDxvsfT/cr5vgNG9hAr2+IGjN9QRWW1O6t5vMweULTeqWLcNOcKsG7WcrFl9M 1IXZd/1v5ApX8UWDedd8ZMHAzCSIwZ8TX234x2skGikAmoH9b0CSUjoPuT/Na3aeyUSK M+LdRwpkfoLRQwzt/eDwOigWqIuVMTgKwbFqqBgkKCytw/ACiMPEtRyXdqjlkh2WYhZX 3T4tY4ZtdVWG4TqzanrQSeZoAM1O84Ht2Ncb69dy4wyy+tP9z15fJiN9MJ37IsQVehMs PRJA== X-Gm-Message-State: AFqh2kqW3DIWGwAmCZUBGFkdR+eKEUSmLRJDK4SyCECDpyYwU7JF/GWU 6/zu/ecNDgMnxYK0KHcndJisn1SAago8073bjZ6MdQjmbBJChQpo4EjI7X6zcLZZd7A3djCbB9P bEyqacOd2Fbh1pGl0YD0PoX9UEuElEq0UQaP/VA== X-Received: by 2002:aa7:8b57:0:b0:589:1130:d3ce with SMTP id i23-20020aa78b57000000b005891130d3cemr1052099pfd.66.1674127308676; Thu, 19 Jan 2023 03:21:48 -0800 (PST) X-Google-Smtp-Source: AMrXdXv8NaWM2xi+pteXBpgFeLxGwK3vp5qL1AtkUtRCbgvNf4HfuPKSZf/ntpuUnLjhfHSR5ilxFBo0F3/7SujE+R4= X-Received: by 2002:aa7:8b57:0:b0:589:1130:d3ce with SMTP id i23-20020aa78b57000000b005891130d3cemr1052095pfd.66.1674127308035; Thu, 19 Jan 2023 03:21:48 -0800 (PST) MIME-Version: 1.0 References: <20230103130324.1329734-1-ahajkova@redhat.com> In-Reply-To: From: Alexandra Petlanova Hajkova Date: Thu, 19 Jan 2023 12:21:35 +0100 Message-ID: Subject: Re: [PATCH v2] gdb: defer warnings when loading separate debug files To: gdb-patches@sourceware.org X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/alternative; boundary="000000000000812e2e05f29c23b3" X-Spam-Status: No, score=-9.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,HTML_MESSAGE,KAM_SHORT,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: --000000000000812e2e05f29c23b3 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 wrote: > >> From: Alexandra H=C3=A1jkov=C3=A1 >> >> 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 >> *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 !=3D NULL >> && filename_cmp (bfd_get_filename (abfd.get ()), >> - objfile_name (objfile)) =3D=3D 0) >> - warning (_("\"%s\": separate debug info file has no debug info"), >> - bfd_get_filename (abfd.get ())); >> + objfile_name (objfile)) =3D=3D 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 !=3D 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 *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 =3D find_separate_debug_file_by_buildid >> (objfile); >> + std::vector warnings_vector; >> + std::string debugfile >> + =3D find_separate_debug_file_by_buildid (objfile, &warnings_vect= or); >> >> if (debugfile.empty ()) >> - debugfile =3D find_separate_debug_file_by_debuglink (objfile); >> + debugfile >> + =3D 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 =3D 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 =3D=3D NULL >> && objfile->separate_debug_objfile_backlink =3D=3D NULL) >> { >> - std::string debugfile =3D find_separate_debug_file_by_buildid >> (objfile); >> + std::string debugfile >> + =3D find_separate_debug_file_by_buildid (objfile, &warnings_vect= or); >> >> if (debugfile.empty ()) >> - debugfile =3D find_separate_debug_file_by_debuglink (objfile); >> + debugfile =3D 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 =3D 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; >> @@ -1335,13 +1336,16 @@ separate_debug_file_exists (const std::string >> &name, unsigned long crc, >> } >> } >> >> - if (verified_as_different || parent_crc !=3D 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 !=3D 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 *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 =3D dir; >> debugfile +=3D 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 +=3D "/"; >> debugfile +=3D 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 +=3D dir_notarget; >> debugfile +=3D 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 =3D NULL; >> @@ -1466,7 +1475,8 @@ find_separate_debug_file (const char *dir, >> debugfile +=3D "/"; >> debugfile +=3D 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 +=3D "/"; >> debugfile +=3D 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] =3D '\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; >> >> @@ -1544,7 +1555,8 @@ find_separate_debug_file_by_debuglink (struct >> objfile *objfile) >> >> std::string debugfile >> =3D 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 *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}] =3D=3D -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 =3D=3D "" } { >> + 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 warni= ng >> +# 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] =3D= =3D >> -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] !=3D -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 =3D=3D "" } { >> + 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 g= et >> # 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] =3D=3D 1 && [lindex $args 0] =3D=3D "no-main" = } { >> + if {[lsearch -exact $args "no-main"] !=3D -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=3D${debug_file} ${stripped_file} ${dest}" output] >> - verbose "result is $result" >> - verbose "output is $output" >> - if {$result =3D=3D 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"] =3D=3D -1} { >> + set result [catch "exec $objcopy_program >> --add-gnu-debuglink=3D${debug_file} ${stripped_file} ${dest}" output] >> + verbose "result is $result" >> + verbose "output is $output" >> + if {$result =3D=3D 1} { >> + return 1 >> + } >> } >> >> # Workaround PR binutils/10802: >> -- >> 2.38.1 >> >> --000000000000812e2e05f29c23b3--