aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read-gdb-index.c
diff options
context:
space:
mode:
authorAaron Merey <amerey@redhat.com>2025-01-21 16:09:47 -0500
committerAaron Merey <amerey@redhat.com>2025-01-24 09:57:38 -0500
commit89c07e295b6485e997e7969052aa2ecf7c811409 (patch)
treed4b1c159f76df421c65b622bbfdc0dbad92e1a67 /gdb/dwarf2/read-gdb-index.c
parent8ce1af0a1d8ecdefcd97f006a2f584dd6fd36ea6 (diff)
downloadgdb-users/amerey/download-gdb-index.zip
gdb-users/amerey/download-gdb-index.tar.gz
gdb-users/amerey/download-gdb-index.tar.bz2
gdb/debuginfod: Add .debug_line downloadingusers/amerey/download-gdb-index
ELF/DWARF section downloading allows gdb to download .gdb_index files in order to defer full debuginfo downloads. However .gdb_index does not contain any information regarding source filenames. When a gdb command includes a filename argument (ex. 'break main.c:50'), this results in the mass downloading of all deferred debuginfo so that gdb can search the debuginfo for matching source filenames. This can result in unnecessary downloads. To improve this, have gdb instead download each debuginfo's .debug_line (and .debug_line_str if using DWARF5) when executing these commands. Download full debuginfo only when its .debug_line contains a matching filename. Since the combined size of .debug_line and .debug_line_str is only about 1% the size of the corresponding debuginfo, significant time can be saved by checking these sections before choosing to download an entire debuginfo. This patch also redirects stdout and stderr of the debuginfod server used by testsuite/gdb.debuginfod tests to a server_log standard output file. While adding tests for this patch I ran into an issue where the test server would block when logging to stderr, presumably because the stderr buffer filled up and wasn't being read from. Redirecting the log to a file fixes this and also makes the server log more accessible when debugging test failures.
Diffstat (limited to 'gdb/dwarf2/read-gdb-index.c')
-rw-r--r--gdb/dwarf2/read-gdb-index.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c
index 821874b..507fd9c 100644
--- a/gdb/dwarf2/read-gdb-index.c
+++ b/gdb/dwarf2/read-gdb-index.c
@@ -998,6 +998,9 @@ run_test ()
#endif /* GDB_SELF_TEST */
+struct mapped_debug_line;
+typedef std::unique_ptr<mapped_debug_line> mapped_debug_line_up;
+
struct dwarf2_gdb_index : public dwarf2_base_index_functions
{
/* This dumps minimal information about the index.
@@ -1018,6 +1021,14 @@ struct dwarf2_gdb_index : public dwarf2_base_index_functions
gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
override;
+ /* If OBJFILE's debuginfo download has been deferred, use a mapped_debug_line
+ to generate filenames.
+
+ Otherwise call dwarf2_base_index_functions::map_symbol_filenames. */
+ void map_symbol_filenames (struct objfile *objfile,
+ gdb::function_view<symbol_filename_ftype> fun,
+ bool need_fullname) override;
+
/* Calls dwarf2_base_index_functions::expand_all_symtabs and downloads
debuginfo if necessary. */
void expand_all_symtabs (struct objfile *objfile) override;
@@ -1025,6 +1036,15 @@ struct dwarf2_gdb_index : public dwarf2_base_index_functions
/* Calls dwarf2_base_index_functions::find_last_source_symtab and downloads
debuginfo if necessary. */
struct symtab *find_last_source_symtab (struct objfile *objfile) override;
+
+ /* Filename information related to this .gdb_index. */
+ mapped_debug_line_up mdl;
+
+ /* Return true if any of the filenames in this .gdb_index's .debug_line
+ mapping match FILE_MATCHER. Initializes the mapping if necessary. */
+ bool filename_in_debug_line
+ (objfile *objfile,
+ gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher);
};
void
@@ -1045,6 +1065,23 @@ dwarf2_gdb_index::find_last_source_symtab (struct objfile *objfile)
return dwarf2_base_index_functions::find_last_source_symtab (objfile);
}
+void
+dwarf2_gdb_index::map_symbol_filenames
+ (struct objfile *objfile,
+ gdb::function_view<symbol_filename_ftype> fun,
+ bool need_fullname)
+{
+ if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) != 0)
+ {
+ if (mdl == nullptr)
+ mdl.reset (new mapped_debug_line (objfile));
+ mdl->map_filenames (fun, need_fullname);
+ }
+ else
+ dwarf2_base_index_functions::map_symbol_filenames (objfile, fun,
+ need_fullname);
+}
+
/* This dumps minimal information about the index.
It is called via "mt print objfiles".
One use is to verify .gdb_index has been loaded by the
@@ -1161,6 +1198,17 @@ dw2_expand_marked_cus
}
bool
+dwarf2_gdb_index::filename_in_debug_line
+ (objfile *objfile,
+ gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher)
+{
+ if (mdl == nullptr)
+ mdl.reset (new mapped_debug_line (objfile));
+
+ return mdl->contains_matching_filename (file_matcher);
+}
+
+bool
dwarf2_gdb_index::expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
@@ -1173,7 +1221,22 @@ dwarf2_gdb_index::expand_symtabs_matching
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
+ if (file_matcher != nullptr)
+ {
+ if ((objfile->flags & OBJF_DOWNLOAD_DEFERRED) == 0)
+ dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
+ else if (filename_in_debug_line (objfile, file_matcher))
+ {
+ /* If OBJFILE's debuginfo hasn't been downloaded and there is a file
+ name to be matched, download the .debug_line (and possibly
+ .debug_line_str) separately. Search the separate .debug_line for
+ a match. If there is a match, then download the full debuginfo.
+ Return early to move on to expanding symtabs in the debuginfo
+ objfile. */
+ read_full_dwarf_from_debuginfod (objfile);
+ return true;
+ }
+ }
/* This invariant is documented in quick-functions.h. */
gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);