https://github.com/GeorgeHuyubo updated https://github.com/llvm/llvm-project/pull/134563
>From 4c4a2bf0883fee1939ed6dd4c55826688d75466c Mon Sep 17 00:00:00 2001 From: George Hu <georgehuy...@gmail.com> Date: Thu, 10 Apr 2025 13:03:43 -0700 Subject: [PATCH] Add download time for each module in statistics --- lldb/include/lldb/Core/PluginManager.h | 7 ++-- lldb/include/lldb/Symbol/ObjectFile.h | 4 +++ lldb/include/lldb/Symbol/SymbolFile.h | 5 +++ lldb/include/lldb/Target/Statistics.h | 1 + lldb/source/Core/DynamicLoader.cpp | 36 ++++++++++++++++--- lldb/source/Core/ModuleList.cpp | 14 ++++++-- lldb/source/Core/PluginManager.cpp | 16 ++++++--- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 28 ++++++++++++--- .../SymbolFile/DWARF/SymbolFileDWARF.h | 3 ++ .../SymbolVendor/ELF/SymbolVendorELF.cpp | 24 ++++++++++--- lldb/source/Target/Statistics.cpp | 9 +++++ 11 files changed, 125 insertions(+), 22 deletions(-) diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index a6dab045adf27..dfa7bfa6eb9da 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -377,11 +377,14 @@ class PluginManager { static SymbolLocatorCreateInstance GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx); - static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec); + static ModuleSpec + LocateExecutableObjectFile(const ModuleSpec &module_spec, + std::string *locator_name = nullptr); static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec, - const FileSpecList &default_search_paths); + const FileSpecList &default_search_paths, + std::string *locator_name = nullptr); static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index cfcca04a76de8..27357b5b4194d 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -13,6 +13,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/Symtab.h" #include "lldb/Symbol/UnwindTable.h" +#include "lldb/Target/Statistics.h" #include "lldb/Utility/AddressableBits.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" @@ -589,6 +590,8 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>, /// this routine to set eTypeDebugInfo when loading debug link files. virtual void SetType(Type type) { m_type = type; } + virtual StatsDuration &GetDownloadTime() { return m_download_time; } + /// The object file should be able to calculate the strata of the object /// file. /// @@ -752,6 +755,7 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>, protected: // Member variables. + StatsDuration m_download_time; ///< Time to download the object file FileSpec m_file; Type m_type; Strata m_strata; diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index f35d3ee9f22ae..2e69acbe34c21 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -422,6 +422,11 @@ class SymbolFile : public PluginInterface { /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Return the time it took to download any extra symbol files. + /// + /// \returns 0.0 if no extra symbol files need to be downloaded + virtual StatsDuration::Duration GetSymbolDownloadTime() { return {}; } + /// Reset the statistics for the symbol file. virtual void ResetStatistics() {} diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h index ee365357fcf31..2d3a7fcceec53 100644 --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -122,6 +122,7 @@ struct ModuleStats { double symtab_index_time = 0.0; double debug_parse_time = 0.0; double debug_index_time = 0.0; + double symbol_download_time = 0.0; uint64_t debug_info_size = 0; bool symtab_loaded_from_cache = false; bool symtab_saved_to_cache = false; diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index 76c71d2a49a48..cd9a92db50be4 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/Progress.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" @@ -25,6 +26,8 @@ #include "lldb/Utility/Log.h" #include "lldb/lldb-private-interfaces.h" +#include "Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h" + #include "llvm/ADT/StringRef.h" #include <memory> @@ -243,15 +246,40 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( // find an executable and symbol file. if (!module_sp) { FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); - module_spec.GetSymbolFileSpec() = - PluginManager::LocateExecutableSymbolFile(module_spec, search_paths); - ModuleSpec objfile_module_spec = - PluginManager::LocateExecutableObjectFile(module_spec); + StatsDuration symbol_duration; + std::string symbol_locator_name; + StatsDuration object_duration; + std::string object_locator_name; + ModuleSpec objfile_module_spec; + { + ElapsedTime elapsed(symbol_duration); + module_spec.GetSymbolFileSpec() = + PluginManager::LocateExecutableSymbolFile(module_spec, search_paths, + &symbol_locator_name); + } + { + ElapsedTime elapsed(object_duration); + objfile_module_spec = PluginManager::LocateExecutableObjectFile( + module_spec, &object_locator_name); + } module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec(); if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) && FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) { module_sp = std::make_shared<Module>(module_spec); } + if (module_sp) { + if (object_locator_name == + SymbolLocatorDebuginfod::GetPluginNameStatic() && + module_sp->GetObjectFile()) + module_sp->GetObjectFile()->GetDownloadTime() += object_duration; + if (symbol_locator_name == + SymbolLocatorDebuginfod::GetPluginNameStatic()) { + const auto symfile = module_sp->GetSymbolFile(); + if (symfile) { + symfile->GetObjectFile()->GetDownloadTime() += symbol_duration; + } + } + } } // If we haven't found a binary, or we don't have a SymbolFile, see diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 2b8ccab2406c6..9ad53cbf2d390 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ModuleList.h" +#include "Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" @@ -917,9 +918,14 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, // Fixup the incoming path in case the path points to a valid file, yet the // arch or UUID (if one was passed in) don't match. - ModuleSpec located_binary_modulespec = - PluginManager::LocateExecutableObjectFile(module_spec); - + ModuleSpec located_binary_modulespec; + StatsDuration locate_duration; + std::string locator_name; + { + ElapsedTime elapsed(locate_duration); + located_binary_modulespec = + PluginManager::LocateExecutableObjectFile(module_spec, &locator_name); + } // Don't look for the file if it appears to be the same one we already // checked for above... if (located_binary_modulespec.GetFileSpec() != module_file_spec) { @@ -992,6 +998,8 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, // By getting the object file we can guarantee that the architecture // matches if (module_sp && module_sp->GetObjectFile()) { + if (locator_name == SymbolLocatorDebuginfod::GetPluginNameStatic()) + module_sp->GetObjectFile()->GetDownloadTime() += locate_duration; if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary) { module_sp.reset(); diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index e6cb248ef31ce..d10fc00b5014d 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -1217,28 +1217,36 @@ PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) { } ModuleSpec -PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) { +PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec, + std::string *locator_name) { auto instances = GetSymbolLocatorInstances().GetSnapshot(); for (auto &instance : instances) { if (instance.locate_executable_object_file) { std::optional<ModuleSpec> result = instance.locate_executable_object_file(module_spec); - if (result) + if (result) { + if (locator_name) + *locator_name = instance.name; return *result; + } } } return {}; } FileSpec PluginManager::LocateExecutableSymbolFile( - const ModuleSpec &module_spec, const FileSpecList &default_search_paths) { + const ModuleSpec &module_spec, const FileSpecList &default_search_paths, + std::string *locator_name) { auto instances = GetSymbolLocatorInstances().GetSnapshot(); for (auto &instance : instances) { if (instance.locate_executable_symbol_file) { std::optional<FileSpec> result = instance.locate_executable_symbol_file( module_spec, default_search_paths); - if (result) + if (result) { + if (locator_name) + *locator_name = instance.name; return *result; + } } } return {}; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index b95159d882bc7..a2f8bede53f84 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -32,6 +32,7 @@ #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" @@ -4250,13 +4251,18 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() { ModuleSpec module_spec; module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec(); FileSpec dwp_filespec; + StatsDuration duration; + std::string locator_name; for (const auto &symfile : symfiles.files()) { module_spec.GetSymbolFileSpec() = FileSpec(symfile.GetPath() + ".dwp", symfile.GetPathStyle()); LLDB_LOG(log, "Searching for DWP using: \"{0}\"", module_spec.GetSymbolFileSpec()); - dwp_filespec = - PluginManager::LocateExecutableSymbolFile(module_spec, search_paths); + { + ElapsedTime elapsed(duration); + dwp_filespec = PluginManager::LocateExecutableSymbolFile( + module_spec, search_paths, &locator_name); + } if (FileSystem::Instance().Exists(dwp_filespec)) { break; } @@ -4267,8 +4273,12 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() { // find the correct DWP file, as the Debuginfod plugin uses *only* this // data to correctly match the DWP file with the binary. module_spec.GetUUID() = m_objfile_sp->GetUUID(); - dwp_filespec = - PluginManager::LocateExecutableSymbolFile(module_spec, search_paths); + duration.reset(); + { + ElapsedTime elapsed(duration); + dwp_filespec = PluginManager::LocateExecutableSymbolFile( + module_spec, search_paths, &locator_name); + } } if (FileSystem::Instance().Exists(dwp_filespec)) { LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec); @@ -4279,6 +4289,8 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() { FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp, dwp_file_data_offset); if (dwp_obj_file) { + if (locator_name == SymbolLocatorDebuginfod::GetPluginNameStatic()) + dwp_obj_file->GetDownloadTime() += duration; m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>( *this, dwp_obj_file, DIERef::k_file_index_mask); } @@ -4349,6 +4361,14 @@ LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) { return LanguageTypeFromDWARF(lang); } +StatsDuration::Duration SymbolFileDWARF::GetSymbolDownloadTime() { + StatsDuration total_time; + total_time += GetObjectFile()->GetDownloadTime(); + if (m_dwp_symfile) + total_time += m_dwp_symfile->GetObjectFile()->GetDownloadTime(); + return total_time; +} + StatsDuration::Duration SymbolFileDWARF::GetDebugInfoIndexTime() { if (m_index) return m_index->GetIndexTime(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 7309f7a86b659..b644ba9c152b9 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -309,6 +309,9 @@ class SymbolFileDWARF : public SymbolFileCommon { StatsDuration::Duration GetDebugInfoParseTime() override { return m_parse_time; } + + StatsDuration::Duration GetSymbolDownloadTime() override; + StatsDuration::Duration GetDebugInfoIndexTime() override; StatsDuration &GetDebugInfoParseTimeRef() { return m_parse_time; } diff --git a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp index a2c3825cd537f..16a147047036f 100644 --- a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -21,6 +21,8 @@ #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" +#include "Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h" + using namespace lldb; using namespace lldb_private; @@ -103,14 +105,25 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, module_spec.GetSymbolFileSpec() = fspec; module_spec.GetUUID() = uuid; FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); - FileSpec dsym_fspec = - PluginManager::LocateExecutableSymbolFile(module_spec, search_paths); + StatsDuration duration; + FileSpec dsym_fspec; + std::string locator_name; + { + ElapsedTime elapsed(duration); + dsym_fspec = PluginManager::LocateExecutableSymbolFile( + module_spec, search_paths, &locator_name); + } if (!dsym_fspec || IsDwpSymbolFile(module_sp, dsym_fspec)) { // If we have a stripped binary or if we have a DWP file, SymbolLocator // plugins may be able to give us an unstripped binary or an // 'only-keep-debug' stripped file. - ModuleSpec unstripped_spec = - PluginManager::LocateExecutableObjectFile(module_spec); + ModuleSpec unstripped_spec; + duration.reset(); + { + ElapsedTime elapsed(duration); + unstripped_spec = + PluginManager::LocateExecutableObjectFile(module_spec, &locator_name); + } if (!unstripped_spec) return nullptr; // The default SymbolLocator plugin returns the original binary if no other @@ -127,7 +140,8 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, dsym_file_data_sp, dsym_file_data_offset); if (!dsym_objfile_sp) return nullptr; - + if (locator_name == SymbolLocatorDebuginfod::GetPluginNameStatic()) + dsym_objfile_sp->GetDownloadTime() += duration; // This objfile is for debugging purposes. Sadly, ObjectFileELF won't // be able to figure this out consistently as the symbol file may not // have stripped the code sections, etc. diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp index b5d2e7bda1edf..52a2d770dac37 100644 --- a/lldb/source/Target/Statistics.cpp +++ b/lldb/source/Target/Statistics.cpp @@ -71,6 +71,7 @@ json::Value ModuleStats::ToJSON() const { module.try_emplace("debugInfoHadIncompleteTypes", debug_info_had_incomplete_types); module.try_emplace("symbolTableStripped", symtab_stripped); + module.try_emplace("symbolDownloadTime", symbol_download_time); if (!symfile_path.empty()) module.try_emplace("symbolFilePath", symfile_path); @@ -288,6 +289,7 @@ llvm::json::Value DebuggerStats::ReportStatistics( json::Array json_targets; json::Array json_modules; + double symbol_download_time = 0.0; double symtab_parse_time = 0.0; double symtab_index_time = 0.0; double debug_parse_time = 0.0; @@ -345,6 +347,11 @@ llvm::json::Value DebuggerStats::ReportStatistics( ++debug_index_saved; module_stat.debug_index_time = sym_file->GetDebugInfoIndexTime().count(); module_stat.debug_parse_time = sym_file->GetDebugInfoParseTime().count(); + module_stat.symbol_download_time += + sym_file->GetSymbolDownloadTime().count(); + if (sym_file->GetObjectFile() != module->GetObjectFile()) + module_stat.symbol_download_time += + module->GetObjectFile()->GetDownloadTime().get().count(); module_stat.debug_info_size = sym_file->GetDebugInfoSize(load_all_debug_info); module_stat.symtab_stripped = module->GetObjectFile()->IsStripped(); @@ -361,6 +368,7 @@ llvm::json::Value DebuggerStats::ReportStatistics( if (module_stat.debug_info_had_variable_errors) ++num_modules_with_variable_errors; } + symbol_download_time += module_stat.symbol_download_time; symtab_parse_time += module_stat.symtab_parse_time; symtab_index_time += module_stat.symtab_index_time; debug_parse_time += module_stat.debug_parse_time; @@ -391,6 +399,7 @@ llvm::json::Value DebuggerStats::ReportStatistics( } json::Object global_stats{ + {"totalSymbolDownloadTime", symbol_download_time}, {"totalSymbolTableParseTime", symtab_parse_time}, {"totalSymbolTableIndexTime", symtab_index_time}, {"totalSymbolTablesLoadedFromCache", symtabs_loaded}, _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits