[Lldb-commits] [lldb] Add locate time and all symbol file path for each module in statistics (PR #134563)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Apr 9 15:45:59 PDT 2025
https://github.com/GeorgeHuyubo updated https://github.com/llvm/llvm-project/pull/134563
>From 85bee8e66fcbc7b2001e2c06499b3458a197be25 Mon Sep 17 00:00:00 2001
From: George Hu <georgehuyubo at gmail.com>
Date: Tue, 8 Apr 2025 18:12:29 -0700
Subject: [PATCH 1/2] Add locate time for each module in statistics
---
lldb/include/lldb/Symbol/ObjectFile.h | 4 ++++
lldb/include/lldb/Symbol/SymbolFile.h | 5 +++++
lldb/include/lldb/Target/Statistics.h | 1 +
lldb/source/Core/ModuleList.cpp | 11 ++++++++---
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 13 +++++++++++++
.../Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 3 +++
.../SymbolVendor/ELF/SymbolVendorELF.cpp | 18 ++++++++++++++----
lldb/source/Target/Statistics.cpp | 8 ++++++++
8 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index cfcca04a76de8..0a782f28dc947 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 &GetLocateTime() { return m_locate_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_locate_time; ///< Time to locate 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..6bea7c3e90a77 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 locate any extra symbol files.
+ ///
+ /// \returns 0.0 if no extra symbol files need to be located
+ virtual StatsDuration::Duration GetSymbolLocateTime() { 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..1fbd3c57efaa6 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_locate_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/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 2b8ccab2406c6..45dbaf4c014c9 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -917,9 +917,13 @@ 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;
+ {
+ ElapsedTime elapsed(locate_duration);
+ located_binary_modulespec =
+ PluginManager::LocateExecutableObjectFile(module_spec);
+ }
// 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 +996,7 @@ 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()) {
+ module_sp->GetObjectFile()->GetLocateTime() += locate_duration;
if (module_sp->GetObjectFile()->GetType() ==
ObjectFile::eTypeStubLibrary) {
module_sp.reset();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b95159d882bc7..a3c809945d9ce 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4250,11 +4250,13 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
ModuleSpec module_spec;
module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec();
FileSpec dwp_filespec;
+ StatsDuration duration;
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());
+ ElapsedTime elapsed(duration);
dwp_filespec =
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
if (FileSystem::Instance().Exists(dwp_filespec)) {
@@ -4267,6 +4269,8 @@ 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();
+ duration.reset();
+ ElapsedTime elapsed(duration);
dwp_filespec =
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
}
@@ -4279,6 +4283,7 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp,
dwp_file_data_offset);
if (dwp_obj_file) {
+ dwp_obj_file->GetLocateTime() += duration;
m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>(
*this, dwp_obj_file, DIERef::k_file_index_mask);
}
@@ -4349,6 +4354,14 @@ LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) {
return LanguageTypeFromDWARF(lang);
}
+StatsDuration::Duration SymbolFileDWARF::GetSymbolLocateTime() {
+ StatsDuration total_time;
+ total_time += GetObjectFile()->GetLocateTime();
+ if (m_dwp_symfile)
+ total_time += m_dwp_symfile->GetObjectFile()->GetLocateTime();
+ 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..a938fd9ccf306 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 GetSymbolLocateTime() 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..b4fbaa2bc6754 100644
--- a/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -103,14 +103,23 @@ 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;
+ {
+ ElapsedTime elapsed(duration);
+ dsym_fspec =
+ PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
+ }
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);
+ }
if (!unstripped_spec)
return nullptr;
// The default SymbolLocator plugin returns the original binary if no other
@@ -128,6 +137,7 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
if (!dsym_objfile_sp)
return nullptr;
+ dsym_objfile_sp->GetLocateTime() += 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..cd25d1d3e2bf7 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("symbolLocateTime", symbol_locate_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_locate_time = 0.0;
double symtab_parse_time = 0.0;
double symtab_index_time = 0.0;
double debug_parse_time = 0.0;
@@ -345,6 +347,10 @@ 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_locate_time += sym_file->GetSymbolLocateTime().count();
+ if (sym_file->GetObjectFile() != module->GetObjectFile())
+ module_stat.symbol_locate_time +=
+ module->GetObjectFile()->GetLocateTime().get().count();
module_stat.debug_info_size =
sym_file->GetDebugInfoSize(load_all_debug_info);
module_stat.symtab_stripped = module->GetObjectFile()->IsStripped();
@@ -361,6 +367,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(
if (module_stat.debug_info_had_variable_errors)
++num_modules_with_variable_errors;
}
+ symbol_locate_time += module_stat.symbol_locate_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 +398,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(
}
json::Object global_stats{
+ {"totalSymbolLocateTime", symbol_locate_time},
{"totalSymbolTableParseTime", symtab_parse_time},
{"totalSymbolTableIndexTime", symtab_index_time},
{"totalSymbolTablesLoadedFromCache", symtabs_loaded},
>From 1cafe599de23343947186c696d43969128676bd9 Mon Sep 17 00:00:00 2001
From: George Hu <georgehuyubo at gmail.com>
Date: Wed, 9 Apr 2025 13:35:58 -0700
Subject: [PATCH 2/2] Add all symfile path in statistic
---
lldb/include/lldb/Symbol/SymbolFile.h | 2 ++
lldb/include/lldb/Target/Statistics.h | 2 +-
.../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 16 ++++++++++++++++
.../Plugins/SymbolFile/DWARF/SymbolFileDWARF.h | 2 ++
lldb/source/Symbol/SymbolFile.cpp | 6 ++++++
lldb/source/Target/Statistics.cpp | 16 +++++++++++-----
6 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index 6bea7c3e90a77..e08fec14a3e90 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -355,6 +355,8 @@ class SymbolFile : public PluginInterface {
virtual const ObjectFile *GetObjectFile() const = 0;
virtual ObjectFile *GetMainObjectFile() = 0;
+ virtual std::vector<ObjectFile *> GetAllObjectFiles();
+
virtual std::vector<std::unique_ptr<CallEdge>>
ParseCallEdgesInFunction(UserID func_id) {
return {};
diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h
index 1fbd3c57efaa6..9cd5f1fe232cc 100644
--- a/lldb/include/lldb/Target/Statistics.h
+++ b/lldb/include/lldb/Target/Statistics.h
@@ -111,7 +111,7 @@ struct ModuleStats {
std::string uuid;
std::string triple;
// Path separate debug info file, or empty if none.
- std::string symfile_path;
+ std::vector<std::string> symfile_path;
// If the debug info is contained in multiple files where each one is
// represented as a separate lldb_private::Module, then these are the
// identifiers of these modules in the global module list. This allows us to
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index a3c809945d9ce..eb19d608ae26d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4354,6 +4354,22 @@ LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) {
return LanguageTypeFromDWARF(lang);
}
+std::vector<ObjectFile *> SymbolFileDWARF::GetAllObjectFiles() {
+ std::vector<ObjectFile *> object_files;
+ object_files.push_back(m_objfile_sp.get());
+ if (m_dwp_symfile) {
+ std::vector<ObjectFile *> dwp_files = m_dwp_symfile->GetAllObjectFiles();
+ object_files.insert(object_files.end(), dwp_files.begin(), dwp_files.end());
+ }
+ if (m_debug_map_symfile) {
+ std::vector<ObjectFile *> debug_map_files =
+ m_debug_map_symfile->GetAllObjectFiles();
+ object_files.insert(object_files.end(), debug_map_files.begin(),
+ debug_map_files.end());
+ }
+ return object_files;
+}
+
StatsDuration::Duration SymbolFileDWARF::GetSymbolLocateTime() {
StatsDuration total_time;
total_time += GetObjectFile()->GetLocateTime();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index a938fd9ccf306..5c64ccded6ebd 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -306,6 +306,8 @@ class SymbolFileDWARF : public SymbolFileCommon {
/// Same as GetLanguage() but reports all C++ versions as C++ (no version).
static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit);
+ std::vector<ObjectFile *> GetAllObjectFiles() override;
+
StatsDuration::Duration GetDebugInfoParseTime() override {
return m_parse_time;
}
diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp
index 94e32b55572dd..08375918ff6e4 100644
--- a/lldb/source/Symbol/SymbolFile.cpp
+++ b/lldb/source/Symbol/SymbolFile.cpp
@@ -150,6 +150,12 @@ void SymbolFile::AssertModuleLock() {
#endif
}
+std::vector<ObjectFile *> SymbolFile::GetAllObjectFiles() {
+ std::vector<ObjectFile *> object_files;
+ object_files.push_back(GetObjectFile());
+ return object_files;
+}
+
SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default;
Symtab *SymbolFileCommon::GetSymtab() {
diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index cd25d1d3e2bf7..aa97d1ece16fe 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -72,8 +72,14 @@ json::Value ModuleStats::ToJSON() const {
debug_info_had_incomplete_types);
module.try_emplace("symbolTableStripped", symtab_stripped);
module.try_emplace("symbolLocateTime", symbol_locate_time);
- if (!symfile_path.empty())
- module.try_emplace("symbolFilePath", symfile_path);
+ if (!symfile_path.empty()) {
+ json::Array symbolfile_path;
+ for (std::string const &path : symfile_path)
+ if (!path.empty())
+ symbolfile_path.emplace_back(path);
+ if (!symbolfile_path.empty())
+ module.try_emplace("symbolFilePaths", std::move(symbolfile_path));
+ }
if (!symfile_modules.empty()) {
json::Array symfile_ids;
@@ -330,9 +336,9 @@ llvm::json::Value DebuggerStats::ReportStatistics(
SymbolFile *sym_file = module->GetSymbolFile(/*can_create=*/false);
if (sym_file) {
if (!summary_only) {
- if (sym_file->GetObjectFile() != module->GetObjectFile())
- module_stat.symfile_path =
- sym_file->GetObjectFile()->GetFileSpec().GetPath();
+ for (ObjectFile *sym_objfile : sym_file->GetAllObjectFiles())
+ module_stat.symfile_path.push_back(
+ sym_objfile->GetFileSpec().GetPath());
ModuleList symbol_modules = sym_file->GetDebugInfoModules();
for (const auto &symbol_module : symbol_modules.Modules())
module_stat.symfile_modules.push_back((intptr_t)symbol_module.get());
More information about the lldb-commits
mailing list