08bfd0a4a7
This commit backports several patches from upstream GDB: 7d21600b31f dd5516bf98f e8c3dafa5f5 1146d27749f 7db795bc67a 8f6c452b5a4 661d98a3331 6234ba17598 27807da5849 7628a997f27 These commits provide a new Python API which allows users to catch the case where GDB tries to load an objfile, but can't find any debug information. I've then added a new patch which uses this Python API to hook into GDB and make suggestions about RPMs to install that could provide missing debug information, this should replace some of the rpm suggestion functionality that is currently implemented within GDB's C++ code, as such I've deleted all of the code related to opening librpm and querying the RPM database. There is still code in GDB which will make suggestions about installing RPMs based on the path to the build-id symlink for the file. This code is hit when a user tries to open a core-file and the corresponding executable can't be found, or if a shared library required by the core-file isn't found. In these cases the librpm lookup would always fail anyway and we'd just suggest that the user try to install the required package based on the path to the build-id symlink, e.g.: Missing separate debuginfo for the main executable file. Try: yum --enablerepo='*debug*' install /usr/local/lib/debug/.build-id/bf/c9fbd13046db58c28ba332e6c991240e775c96 This should still work just as it did before. Now GDB no longer links against librpm I'm able to remove all the librpm related stuff from the configure scripts, which is a nice cleanup. There are a couple of patches: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch gdb-6.6-buildid-locate-rpm.patch which deal exclusively with updating code (added in earlier patches) related to the use of librpm from GDB's C++ code, these patches are removed by this commit. Other patches are changed either by the removal of the librpm code, or as a consequence of that code having been removed. I've also taken the opportunity to fix up some of the test cases which only exist in the Fedora tree so that they will run again. This is mostly just updating the tests to match upstream GDB's current testsuite infrastructure, these are all pretty minor fixes.
191 lines
6.2 KiB
Diff
191 lines
6.2 KiB
Diff
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||
From: Andrew Burgess <aburgess@redhat.com>
|
||
Date: Fri, 13 Oct 2023 16:17:20 +0100
|
||
Subject: gdb-refactor-find-and-add-separate-symbol-file.patch
|
||
|
||
;; Backport upstream commit 6234ba17598.
|
||
|
||
gdb: refactor objfile::find_and_add_separate_symbol_file
|
||
|
||
This is purely a refactoring commit.
|
||
|
||
This commit splits objfile::find_and_add_separate_symbol_file into
|
||
some separate helper functions. My hope is that the steps for looking
|
||
up separate debug information are now clearer.
|
||
|
||
In a later commit I'm going to extend
|
||
objfile::find_and_add_separate_symbol_file, with some additional
|
||
logic, so starting with a simpler function will make the following
|
||
changes easier.
|
||
|
||
When reading objfile::find_and_add_separate_symbol_file after this
|
||
commit, you might be tempted to think that removing the `has_dwarf`
|
||
local variable would be a good additional cleanup. After the next
|
||
commit though it makes more sense to retain this local, so I've left
|
||
this in place for now.
|
||
|
||
There should be no user visible changes after this commit.
|
||
|
||
Approved-By: Tom Tromey <tom@tromey.com>
|
||
|
||
diff --git a/gdb/symfile-debug.c b/gdb/symfile-debug.c
|
||
--- a/gdb/symfile-debug.c
|
||
+++ b/gdb/symfile-debug.c
|
||
@@ -560,68 +560,109 @@ objfile::require_partial_symbols (bool verbose)
|
||
}
|
||
}
|
||
|
||
+/* Call LOOKUP_FUNC to find the filename of a file containing the separate
|
||
+ debug information matching OBJFILE. If LOOKUP_FUNC does return a
|
||
+ filename then open this file and return a std::pair containing the
|
||
+ gdb_bfd_ref_ptr of the open file and the filename returned by
|
||
+ LOOKUP_FUNC, otherwise this function returns an empty pair; the first
|
||
+ item will be nullptr, and the second will be an empty string.
|
||
+
|
||
+ Any warnings generated by this function, or by calling LOOKUP_FUNC are
|
||
+ placed into WARNINGS, these warnings are only displayed to the user if
|
||
+ GDB is unable to find the separate debug information via any route. */
|
||
+static std::pair<gdb_bfd_ref_ptr, std::string>
|
||
+simple_find_and_open_separate_symbol_file
|
||
+ (struct objfile *objfile,
|
||
+ std::string (*lookup_func) (struct objfile *, deferred_warnings *),
|
||
+ deferred_warnings *warnings)
|
||
+{
|
||
+ std::string filename = lookup_func (objfile, warnings);
|
||
+
|
||
+ if (!filename.empty ())
|
||
+ {
|
||
+ gdb_bfd_ref_ptr symfile_bfd
|
||
+ = symfile_bfd_open_no_error (filename.c_str ());
|
||
+ if (symfile_bfd != nullptr)
|
||
+ return { symfile_bfd, filename };
|
||
+ }
|
||
+
|
||
+ return {};
|
||
+}
|
||
+
|
||
+/* Lookup separate debug information for OBJFILE via debuginfod. If
|
||
+ successful the debug information will be have been downloaded into the
|
||
+ debuginfod cache and this function will return a std::pair containing a
|
||
+ gdb_bfd_ref_ptr of the open debug information file and the filename for
|
||
+ the file within the debuginfod cache. If no debug information could be
|
||
+ found then this function returns an empty pair; the first item will be
|
||
+ nullptr, and the second will be an empty string. */
|
||
+
|
||
+static std::pair<gdb_bfd_ref_ptr, std::string>
|
||
+debuginfod_find_and_open_separate_symbol_file (struct objfile * objfile)
|
||
+{
|
||
+ const struct bfd_build_id *build_id
|
||
+ = build_id_bfd_get (objfile->obfd.get ());
|
||
+ const char *filename = bfd_get_filename (objfile->obfd.get ());
|
||
+
|
||
+ if (build_id != nullptr)
|
||
+ {
|
||
+ gdb::unique_xmalloc_ptr<char> symfile_path;
|
||
+ scoped_fd fd (debuginfod_debuginfo_query (build_id->data, build_id->size,
|
||
+ filename, &symfile_path));
|
||
+
|
||
+ if (fd.get () >= 0)
|
||
+ {
|
||
+ /* File successfully retrieved from server. */
|
||
+ gdb_bfd_ref_ptr debug_bfd
|
||
+ (symfile_bfd_open_no_error (symfile_path.get ()));
|
||
+
|
||
+ if (debug_bfd != nullptr
|
||
+ && build_id_verify (debug_bfd.get (),
|
||
+ build_id->size, build_id->data))
|
||
+ return { debug_bfd, std::string (symfile_path.get ()) };
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return {};
|
||
+}
|
||
+
|
||
/* See objfiles.h. */
|
||
|
||
bool
|
||
objfile::find_and_add_separate_symbol_file (symfile_add_flags symfile_flags)
|
||
{
|
||
- bool has_dwarf2 = true;
|
||
+ bool has_dwarf = false;
|
||
|
||
deferred_warnings warnings;
|
||
|
||
- std::string debugfile
|
||
- = find_separate_debug_file_by_buildid (this, &warnings);
|
||
-
|
||
- if (debugfile.empty ())
|
||
- debugfile = find_separate_debug_file_by_debuglink (this, &warnings);
|
||
+ gdb_bfd_ref_ptr debug_bfd;
|
||
+ std::string filename;
|
||
|
||
- if (!debugfile.empty ())
|
||
- {
|
||
- gdb_bfd_ref_ptr debug_bfd
|
||
- (symfile_bfd_open_no_error (debugfile.c_str ()));
|
||
+ std::tie (debug_bfd, filename) = simple_find_and_open_separate_symbol_file
|
||
+ (this, find_separate_debug_file_by_buildid, &warnings);
|
||
|
||
- if (debug_bfd != nullptr)
|
||
- symbol_file_add_separate (debug_bfd, debugfile.c_str (),
|
||
- symfile_flags, this);
|
||
- }
|
||
- else
|
||
- {
|
||
- has_dwarf2 = false;
|
||
- const struct bfd_build_id *build_id
|
||
- = build_id_bfd_get (this->obfd.get ());
|
||
- const char *filename = bfd_get_filename (this->obfd.get ());
|
||
-
|
||
- if (build_id != nullptr)
|
||
- {
|
||
- gdb::unique_xmalloc_ptr<char> symfile_path;
|
||
- scoped_fd fd (debuginfod_debuginfo_query (build_id->data,
|
||
- build_id->size,
|
||
- filename,
|
||
- &symfile_path));
|
||
+ if (debug_bfd == nullptr)
|
||
+ std::tie (debug_bfd, filename)
|
||
+ = simple_find_and_open_separate_symbol_file
|
||
+ (this, find_separate_debug_file_by_debuglink, &warnings);
|
||
|
||
- if (fd.get () >= 0)
|
||
- {
|
||
- /* File successfully retrieved from server. */
|
||
- gdb_bfd_ref_ptr debug_bfd
|
||
- (symfile_bfd_open_no_error (symfile_path.get ()));
|
||
+ if (debug_bfd == nullptr)
|
||
+ std::tie (debug_bfd, filename)
|
||
+ = debuginfod_find_and_open_separate_symbol_file (this);
|
||
|
||
- if (debug_bfd != nullptr
|
||
- && build_id_verify (debug_bfd.get (), build_id->size,
|
||
- build_id->data))
|
||
- {
|
||
- symbol_file_add_separate (debug_bfd, symfile_path.get (),
|
||
- symfile_flags, this);
|
||
- has_dwarf2 = true;
|
||
- }
|
||
- }
|
||
- }
|
||
+ if (debug_bfd != nullptr)
|
||
+ {
|
||
+ symbol_file_add_separate (debug_bfd, filename.c_str (), symfile_flags,
|
||
+ this);
|
||
+ has_dwarf = true;
|
||
}
|
||
- /* If all the methods to collect the debuginfo failed, print the
|
||
- warnings, this is a no-op if there are no warnings. */
|
||
- if (debugfile.empty () && !has_dwarf2)
|
||
+
|
||
+ /* If we still have not got a separate debug symbol file, then
|
||
+ emit any warnings we've collected so far. */
|
||
+ if (!has_dwarf)
|
||
warnings.emit ();
|
||
|
||
- return has_dwarf2;
|
||
+ return has_dwarf;
|
||
}
|
||
|
||
|