diff options
author | Aaron Merey <amerey@redhat.com> | 2025-01-21 16:09:47 -0500 |
---|---|---|
committer | Aaron Merey <amerey@redhat.com> | 2025-01-24 09:57:38 -0500 |
commit | 89c07e295b6485e997e7969052aa2ecf7c811409 (patch) | |
tree | d4b1c159f76df421c65b622bbfdc0dbad92e1a67 /gdb/dwarf2/read-gdb-index.c | |
parent | 8ce1af0a1d8ecdefcd97f006a2f584dd6fd36ea6 (diff) | |
download | gdb-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.c | 65 |
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); |