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 2EE4E3858C52 for ; Thu, 19 Jan 2023 11:38:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2EE4E3858C52 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=1674128326; 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=bSwbRLbgqHY1AvHW+O4qP8zSNzyMfeVj7kV0mBDPxqA=; b=KeXVycxcyegRa7EQh4sOXcnmoxioZeJi+MNSfLFBcedKw6mmLEurTD8yJFWrM+b7AkO6Bl joM5YXpzhVjxGJMSZ0+bRxTGQnTZ35Fgm7KEGxQqxBu5yii5X1mEk/WdRpwXi48g08WTni IQt+wfkcCfTlssC1lRWtm8xp1QLKtr4= Received: from mail-qv1-f69.google.com (mail-qv1-f69.google.com [209.85.219.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-475-PfgB1ZQyMvaIHLO3I9nadg-1; Thu, 19 Jan 2023 06:38:45 -0500 X-MC-Unique: PfgB1ZQyMvaIHLO3I9nadg-1 Received: by mail-qv1-f69.google.com with SMTP id y6-20020a0cec06000000b005346d388b7aso859651qvo.6 for ; Thu, 19 Jan 2023 03:38:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:references :in-reply-to:subject:to:from:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=fYrEobYVHRZz5fsPM9cXIBz0u3EpHzsKvxwM3HaOd8U=; b=4HXk7VlNvOypFRKcMcP2NeYHRZ9L8GFMAJ4KRArj6J1bX4rWRhqBKhlldnUnngSDSD ZFccbUnRlBB6WXspa9vSHKv6JnPcLn9Pq1X0Od5tEflq4w6tNOKfFSrk9xbnYMEK94ma kwsBLqpUC937F6lptplXALbm5JbW2P0lea7UPD+9p4B8xaYimvYi6m2NWmOEq0TBqKTC QbOr4CM/lfR8e3XtZtnXx0XMB4VH0/jSeBU1DrNITBQkNrXV5SynVQfMRccEZZdIl0+J dornf8vAUvw0YqX1o55isiW1w6zMQbSiml9W7+Hw4A9G2ND35BmJsDYwRzJOk7zHP+kG BLWA== X-Gm-Message-State: AFqh2kr8z9iAWnLOWc+df/BkQYA7HOGPrfSm2QuRPcd2MS60tHjsjRAI AiYVHEtKXtOdYo0RRMoLi9gRV7G3PAcfkkHmDFejLiQuRTbrnHtIETl6YJSyosv3+OMwCO6SB+R DfbhFLMCM4e7sunfvj2VlAg== X-Received: by 2002:ad4:4501:0:b0:531:bb84:b9ef with SMTP id k1-20020ad44501000000b00531bb84b9efmr45199106qvu.46.1674128324616; Thu, 19 Jan 2023 03:38:44 -0800 (PST) X-Google-Smtp-Source: AMrXdXvyINXeBkoXHunie9rV7fGi1PNzuJThkYPd9fCA8nsMNxOUL1ofqAjYCngET7pihfU7YFL4OA== X-Received: by 2002:ad4:4501:0:b0:531:bb84:b9ef with SMTP id k1-20020ad44501000000b00531bb84b9efmr45199027qvu.46.1674128323962; Thu, 19 Jan 2023 03:38:43 -0800 (PST) Received: from localhost (95.72.115.87.dyn.plus.net. [87.115.72.95]) by smtp.gmail.com with ESMTPSA id u24-20020a37ab18000000b006f9c2be0b4bsm7735765qke.135.2023.01.19.03.38.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Jan 2023 03:38:43 -0800 (PST) From: Andrew Burgess To: =?us-ascii?Q?AlexandraH=3D=3FUTF-8=3FB=3Fw6E=3D=3F=3Djkov=3D=3FUTF-8?= =?us-ascii?Q?=3FB=3Fw6E=3D=3F=3D?=@sourceware.org, gdb-patches@sourceware.org Subject: Re: [PATCH v2] gdb: defer warnings when loading separate debug files In-Reply-To: <20230103130324.1329734-1-ahajkova@redhat.com> References: <20230103130324.1329734-1-ahajkova@redhat.com> Date: Thu, 19 Jan 2023 11:38:41 +0000 Message-ID: <87o7queou6.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,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: AlexandraH=C3=A1jkov=C3=A1@sourceware.org writes: > 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_mism= atch-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 mis= match" > warning. A local debuginfod server is setup to supply the correct debug f= ile, > 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 tri= ggers > 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 ev= entually. > 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-warnin= g.c > create mode 100644 gdb/testsuite/gdb.debuginfod/build-id-no-debug-warnin= g.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. */ > =20 > std::string > -find_separate_debug_file_by_buildid (struct objfile *objfile) > +find_separate_debug_file_by_buildid (struct objfile *objfile, > +=09=09=09=09 std::vector *warnings_vector) > { > const struct bfd_build_id *build_id; > =20 > @@ -219,9 +220,16 @@ find_separate_debug_file_by_buildid (struct objfile = *objfile) > /* Prevent looping on a stripped .debug file. */ > if (abfd !=3D NULL > =09 && filename_cmp (bfd_get_filename (abfd.get ()), > -=09=09=09 objfile_name (objfile)) =3D=3D 0) > -=09warning (_("\"%s\": separate debug info file has no debug info"), > -=09=09 bfd_get_filename (abfd.get ())); > +=09=09=09 objfile_name (objfile)) =3D=3D 0) { > + if (separate_debug_file_debug) > + gdb_printf (gdb_stdlog, > + (_( "\"%s\": separate debug info file has no d= ebug 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) > =09return 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 b= uild_id_len, > =20 > /* 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 mechanis= m 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. */ > =20 > extern std::string find_separate_debug_file_by_buildid > - (struct objfile *objfile); > + (struct objfile *objfile, std::vector *warnings_vector); > =20 > /* Return an hex-string representation of BUILD_ID. */ > =20 > 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 (obj= file); > + std::vector warnings_vector; > + std::string debugfile > +=09=3D find_separate_debug_file_by_buildid (objfile, &warnings_vector); > =20 > if (debugfile.empty ()) > -=09debugfile =3D find_separate_debug_file_by_debuglink (objfile); > +=09debugfile > +=09 =3D find_separate_debug_file_by_debuglink (objfile, &warnings_vecto= r); > =20 > if (!debugfile.empty ()) > =09{ > @@ -746,6 +749,11 @@ coff_symfile_read (struct objfile *objfile, symfile_= add_flags symfile_flags) > =09 symbol_file_add_separate (debug_bfd, debugfile.c_str (), > =09=09=09=09 symfile_flags, objfile); > =09} > + /* If all the methods to collect the debuginfo failed, print any > +=09 warnings that were collected. */ > + if (debugfile.empty () && !warnings_vector.empty ()) > +=09for (const std::string &w : warnings_vector) > +=09 warning ("%s", w.c_str ()); > } > } > =20 > 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, > =09=09=09 symfile_add_flags symfile_flags) > { > bool has_dwarf2 =3D true; > + std::vector warnings_vector; > =20 > if (dwarf2_has_info (objfile, NULL, true)) > dwarf2_initialize_objfile (objfile); > @@ -1213,10 +1214,12 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, > =09 && objfile->separate_debug_objfile =3D=3D NULL > =09 && objfile->separate_debug_objfile_backlink =3D=3D NULL) > { > - std::string debugfile =3D find_separate_debug_file_by_buildid (obj= file); > + std::string debugfile > +=09=3D find_separate_debug_file_by_buildid (objfile, &warnings_vector); > =20 > if (debugfile.empty ()) > -=09debugfile =3D find_separate_debug_file_by_debuglink (objfile); > +=09debugfile =3D find_separate_debug_file_by_debuglink (objfile, > +=09=09=09=09=09=09=09 &warnings_vector); > =20 > if (!debugfile.empty ()) > =09{ > @@ -1258,6 +1261,11 @@ elf_symfile_read_dwarf2 (struct objfile *objfile, > =09=09} > =09 } > =09} > + /* If all the methods to collect the debuginfo failed, print > +=09 the warnings, if there're any. */ > + if (debugfile.empty () && !has_dwarf2 && !warnings_vector.empty ()= ) > +=09for (const std::string &w : warnings_vector) > +=09 warning ("%s", w.c_str ()); > } > =20 > 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; > =20 > static int > separate_debug_file_exists (const std::string &name, unsigned long crc, > -=09=09=09 struct objfile *parent_objfile) > +=09=09=09 struct objfile *parent_objfile, > +=09=09=09 std::vector *warnings_vector) > { > unsigned long file_crc; > int file_crc_p; > @@ -1335,13 +1336,16 @@ separate_debug_file_exists (const std::string &na= me, unsigned long crc, > =09 } > =09} > =20 > - if (verified_as_different || parent_crc !=3D file_crc) > -=09warning (_("the debug information found in \"%s\"" > -=09=09 " does not match \"%s\" (CRC mismatch).\n"), > -=09=09 name.c_str (), objfile_name (parent_objfile)); > - > - if (separate_debug_file_debug) > -=09gdb_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 mis= match).\n"), > + name.c_str (), objfile_name (paren= t_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_objfil= e))); I don't think we want to do this. We shouldn't be switching what the user sees based on whether a debug flag is on or not. I think what you mean is: 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_objfi= le)); 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= ))); } Notice that the GNU style is not to use trailing '{' characters. Also, lines should be indented with a mix of tabs and spaces. Thanks, Andrew > + } > =20 > 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. */ > =20 > static std::string > find_separate_debug_file (const char *dir, > =09=09=09 const char *canon_dir, > =09=09=09 const char *debuglink, > -=09=09=09 unsigned long crc32, struct objfile *objfile) > +=09=09=09 unsigned long crc32, struct objfile *objfile, > +=09=09=09 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; > =20 > - if (separate_debug_file_exists (debugfile, crc32, objfile)) > + if (separate_debug_file_exists (debugfile, crc32, objfile, warnings_ve= ctor)) > return debugfile; > =20 > /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ > @@ -1399,7 +1407,7 @@ find_separate_debug_file (const char *dir, > debugfile +=3D "/"; > debugfile +=3D debuglink; > =20 > - if (separate_debug_file_exists (debugfile, crc32, objfile)) > + if (separate_debug_file_exists (debugfile, crc32, objfile, warnings_ve= ctor)) > return debugfile; > =20 > /* 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; > =20 > - if (separate_debug_file_exists (debugfile, crc32, objfile)) > + if (separate_debug_file_exists (debugfile, crc32, objfile, > +=09=09=09=09 warnings_vector)) > =09return debugfile; > =20 > const char *base_path =3D NULL; > @@ -1466,7 +1475,8 @@ find_separate_debug_file (const char *dir, > =09 debugfile +=3D "/"; > =09 debugfile +=3D debuglink; > =20 > -=09 if (separate_debug_file_exists (debugfile, crc32, objfile)) > +=09 if (separate_debug_file_exists (debugfile, crc32, objfile, > +=09=09=09=09=09 warnings_vector)) > =09 return debugfile; > =20 > =09 /* If the file is in the sysroot, try using its base path in > @@ -1492,10 +1502,11 @@ find_separate_debug_file (const char *dir, > =09 debugfile +=3D "/"; > =09 debugfile +=3D debuglink; > =20 > -=09 if (separate_debug_file_exists (debugfile, crc32, objfile)) > -=09=09return debugfile; > -=09 } > -=09} > + if (separate_debug_file_exists (debugfile, crc32, objfile, > + warnings_vector)) > + return debugfile; > + } > + } > } > =20 > return std::string (); > @@ -1520,11 +1531,11 @@ terminate_after_last_dir_separator (char *path) > path[i + 1] =3D '\0'; > } > =20 > -/* Find separate debuginfo for OBJFILE (using .gnu_debuglink section). > - Returns pathname, or an empty string. */ > +/* See symtab.h. */ > =20 > 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; > =20 > @@ -1544,7 +1555,8 @@ find_separate_debug_file_by_debuglink (struct objfi= le *objfile) > =20 > std::string debugfile > =3D find_separate_debug_file (dir.c_str (), canon_dir.get (), > -=09=09=09=09debuglink.get (), crc32, objfile); > +=09=09=09=09debuglink.get (), crc32, objfile, > +=09=09=09=09warnings_vector); > =20 > if (debugfile.empty ()) > { > @@ -1568,7 +1580,8 @@ find_separate_debug_file_by_debuglink (struct objfi= le *objfile) > =09=09=09=09=09=09=09symlink_dir.get (), > =09=09=09=09=09=09=09debuglink.get (), > =09=09=09=09=09=09=09crc32, > -=09=09=09=09=09=09=09objfile); > +=09=09=09=09=09=09=09objfile, > +=09=09=09=09=09=09=09warnings_vector); > =09=09} > =09 } > =09} > 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 (con= st gdb_bfd_ref_ptr &, > extern void symbol_file_add_separate (const gdb_bfd_ref_ptr &, const cha= r *, > =09=09=09=09 symfile_add_flags, struct objfile *); > =20 > -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); > =20 > /* 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/g= db/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" wa= rning by replacing > +# the build-id based .debug file with the stripped binary and then loadi= ng it to gdb. > +# It then also sets up local debuginfod server with the correct debug fi= le 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} \ > +=09 {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 "" } { > +=09unresolved "failed to start debuginfod server" > +=09return > + } > + > + # 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}" \ > +=09[multi_line \ > +=09 "Reading symbols from ${build_id_debug_file}\\.\\.\\." \ > +=09 "Downloading separate debug info for ${build_id_debug_file}\\.\\= .\\." \ > +=09 "Reading symbols from ${cache}/\[^\r\n\]+\\.\\.\\.(?:\r\nExpandi= ng full symbols from \[^\r\n\]+)*"] \ > +=09"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/testsuit= e/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/testsuit= e/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 t= est > +# 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 warnin= g > +# 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 installe= d. > + 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] $debug= file" > + > +# Test CRC mismatch is reported. > +if {[build_executable crc_mismatch.exp crc_mismatch-2 crc_mismatch-2.c d= ebug] !=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 r= eal one > + # to trigger the "CRC mismatch" warning. > + remote_exec build "mv ${debugfile} [standard_output_file crc_mismatc= h-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 "" } { > +=09unresolved "failed to start debuginfod server" > +=09return > + } > + > + # 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.*" \ > +=09"file [file tail $binfile] cmd on" > + > + # CRC mismatch should not be reported now because the correct debugi= nfo > + # should be fetched from debuginfod. > + gdb_test "file [standard_output_file crc_mismatch-2]" \ > +=09[multi_line \ > +=09 "Reading symbols from ${escapedobjdirsubdir}/crc_mismatch-2\\.\\= .\\." \ > +=09 "Downloading separate debug info for ${escapedobjdirsubdir}/crc_= mismatch-2\\.\\.\\." \ > +=09 "Reading symbols from ${cache}/\[^\r\n\]+\\.\\.\\.(?:\r\nExpandi= ng full symbols from \[^\r\n\]+)*"] \ > +=09 "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" > } > =20 > -# Create stripped files for DEST, replacing it. If ARGS is passed, it i= s 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 failu= re 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 ge= t > # 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} { > =09set result [catch "exec $objcopy_program -N main ${debug_file} ${debu= g_file}-tmp" output] > =09verbose "result is $result" > =09verbose "output is $output" > @@ -7211,15 +7221,17 @@ proc gdb_gnu_strip_debug { dest args } { > =09file rename "${debug_file}-tmp" "${debug_file}" > } > =20 > - # Link the two previous output files together, adding the .gnu_debug= link > - # section to the stripped_file, containing a pointer to the debug_fi= le, > - # save the new file in dest. > - # This will be the regular executable filename, in the usual locatio= n. > - set result [catch "exec $objcopy_program --add-gnu-debuglink=3D${deb= ug_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} { > +=09set result [catch "exec $objcopy_program --add-gnu-debuglink=3D${debu= g_file} ${stripped_file} ${dest}" output] > +=09verbose "result is $result" > +=09verbose "output is $output" > +=09if {$result =3D=3D 1} { > +=09 return 1 > +=09} > } > =20 > # Workaround PR binutils/10802: > --=20 > 2.38.1