Skip to content

Add symbol locator time for each module in statistics #137379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,10 @@ class Module : public std::enable_shared_from_this<Module>,
/// ElapsedTime RAII object.
StatsDuration &GetSymtabIndexTime() { return m_symtab_index_time; }

StatisticsMap &GetSymbolLocatorStatistics() {
return m_symbol_locator_duration_map;
}

void ResetStatistics();

/// \class LookupInfo Module.h "lldb/Core/Module.h"
Expand Down Expand Up @@ -1064,6 +1068,8 @@ class Module : public std::enable_shared_from_this<Module>,
/// time for the symbol tables can be aggregated here.
StatsDuration m_symtab_index_time;

StatisticsMap m_symbol_locator_duration_map;

/// A set of hashes of all warnings and errors, to avoid reporting them
/// multiple times to the same Debugger.
llvm::DenseMap<llvm::stable_hash, std::unique_ptr<std::once_flag>>
Expand Down
7 changes: 5 additions & 2 deletions lldb/include/lldb/Core/PluginManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "lldb/Core/Architecture.h"
#include "lldb/Interpreter/Interfaces/ScriptedInterfaceUsages.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Target/Statistics.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"
Expand Down Expand Up @@ -379,11 +380,13 @@ class PluginManager {
static SymbolLocatorCreateInstance
GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx);

static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec);
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec,
StatisticsMap &map);

static FileSpec
LocateExecutableSymbolFile(const ModuleSpec &module_spec,
const FileSpecList &default_search_paths);
const FileSpecList &default_search_paths,
StatisticsMap &map);

static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
Status &error,
Expand Down
21 changes: 21 additions & 0 deletions lldb/include/lldb/Target/Statistics.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ class ElapsedTime {
}
};

/// A class to count time for plugins
class StatisticsMap {
public:
void add(llvm::StringRef key, double value) {
if (key.empty())
return;
auto it = map.find(key);
if (it == map.end())
map.try_emplace(key, value);
else
it->second += value;
}
void merge(StatisticsMap map_to_merge) {
for (const auto &entry : map_to_merge.map) {
add(entry.first(), entry.second);
}
}
llvm::StringMap<double> map;
};

/// A class to count success/fail statistics.
struct StatsSuccessFail {
StatsSuccessFail(llvm::StringRef n) : name(n.str()) {}
Expand Down Expand Up @@ -118,6 +138,7 @@ struct ModuleStats {
// track down all of the stats that contribute to this module.
std::vector<intptr_t> symfile_modules;
llvm::StringMap<llvm::json::Value> type_system_stats;
StatisticsMap symbol_locator_time;
double symtab_parse_time = 0.0;
double symtab_index_time = 0.0;
uint32_t symtab_symbol_count = 0;
Expand Down
11 changes: 9 additions & 2 deletions lldb/source/Core/DynamicLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,22 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
// find an executable and symbol file.
if (!module_sp) {
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
StatisticsMap symbol_locator_map;
module_spec.GetSymbolFileSpec() =
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths,
symbol_locator_map);
ModuleSpec objfile_module_spec =
PluginManager::LocateExecutableObjectFile(module_spec);
PluginManager::LocateExecutableObjectFile(module_spec,
symbol_locator_map);
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) {
module_sp->GetSymbolLocatorStatistics().merge(symbol_locator_map);
}
}

// If we haven't found a binary, or we don't have a SymbolFile, see
Expand Down
8 changes: 5 additions & 3 deletions lldb/source/Core/ModuleList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,9 +917,10 @@ 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;
StatisticsMap symbol_locator_map;
located_binary_modulespec = PluginManager::LocateExecutableObjectFile(
module_spec, symbol_locator_map);
// 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) {
Expand Down Expand Up @@ -992,6 +993,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->GetSymbolLocatorStatistics().merge(symbol_locator_map);
if (module_sp->GetObjectFile()->GetType() ==
ObjectFile::eTypeStubLibrary) {
module_sp.reset();
Expand Down
25 changes: 19 additions & 6 deletions lldb/source/Core/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1218,12 +1218,18 @@ PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) {
}

ModuleSpec
PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec,
StatisticsMap &map) {
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);
StatsDuration time;
std::optional<ModuleSpec> result;
{
ElapsedTime elapsed(time);
result = instance.locate_executable_object_file(module_spec);
}
map.add(instance.name, time.get().count());
if (result)
return *result;
}
Expand All @@ -1232,12 +1238,19 @@ PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
}

FileSpec PluginManager::LocateExecutableSymbolFile(
const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
const ModuleSpec &module_spec, const FileSpecList &default_search_paths,
StatisticsMap &map) {
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);
StatsDuration time;
std::optional<FileSpec> result;
{
ElapsedTime elapsed(time);
result = instance.locate_executable_symbol_file(module_spec,
default_search_paths);
}
map.add(instance.name, time.get().count());
if (result)
return *result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,8 @@ Status PlatformDarwinKernel::GetSharedModuleKernel(
// append ".dSYM" to the filename for the SymbolFile.
FileSpecList search_paths =
process->GetTarget().GetDebugFileSearchPaths();
FileSpec dsym_fspec =
PluginManager::LocateExecutableSymbolFile(kern_spec, search_paths);
FileSpec dsym_fspec = PluginManager::LocateExecutableSymbolFile(
kern_spec, search_paths, module_sp->GetSymbolLocatorStatistics());
if (FileSystem::Instance().Exists(dsym_fspec))
module_sp->SetSymbolFileFileSpec(dsym_fspec);
if (did_create_ptr)
Expand Down
11 changes: 8 additions & 3 deletions lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,15 @@ Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {
// Lookup UUID locally, before attempting dsymForUUID like action
FileSpecList search_paths =
Target::GetDefaultDebugFileSearchPaths();

StatisticsMap symbol_locator_map;
module_spec.GetSymbolFileSpec() =
PluginManager::LocateExecutableSymbolFile(module_spec,
search_paths);
PluginManager::LocateExecutableSymbolFile(
module_spec, search_paths, symbol_locator_map);
if (module_spec.GetSymbolFileSpec()) {
ModuleSpec executable_module_spec =
PluginManager::LocateExecutableObjectFile(module_spec);
PluginManager::LocateExecutableObjectFile(
module_spec, symbol_locator_map);
if (FileSystem::Instance().Exists(
executable_module_spec.GetFileSpec())) {
module_spec.GetFileSpec() =
Expand All @@ -297,6 +300,8 @@ Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {

if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
ModuleSP module_sp(new Module(module_spec));
module_sp->GetSymbolLocatorStatistics().merge(
symbol_locator_map);
if (module_sp.get() && module_sp->GetObjectFile()) {
// Get the current target executable
ModuleSP exe_module_sp(target.GetExecutableModule());
Expand Down
10 changes: 6 additions & 4 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4245,8 +4245,9 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
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);
dwp_filespec = PluginManager::LocateExecutableSymbolFile(
module_spec, search_paths,
m_objfile_sp->GetModule()->GetSymbolLocatorStatistics());
if (FileSystem::Instance().Exists(dwp_filespec)) {
break;
}
Expand All @@ -4257,8 +4258,9 @@ 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);
dwp_filespec = PluginManager::LocateExecutableSymbolFile(
module_spec, search_paths,
m_objfile_sp->GetModule()->GetSymbolLocatorStatistics());
}
if (FileSystem::Instance().Exists(dwp_filespec)) {
LLDB_LOG(log, "Found DWP file: \"{0}\"", dwp_filespec);
Expand Down
9 changes: 4 additions & 5 deletions lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,14 @@ 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);
FileSpec dsym_fspec = PluginManager::LocateExecutableSymbolFile(
module_spec, search_paths, module_sp->GetSymbolLocatorStatistics());
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 = PluginManager::LocateExecutableObjectFile(
module_spec, module_sp->GetSymbolLocatorStatistics());
if (!unstripped_spec)
return nullptr;
// The default SymbolLocator plugin returns the original binary if no other
Expand All @@ -127,7 +127,6 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
dsym_file_data_sp, dsym_file_data_offset);
if (!dsym_objfile_sp)
return nullptr;

// 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
module_spec.GetUUID() = module_sp->GetUUID();
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
dsym_fspec =
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);

dsym_fspec = PluginManager::LocateExecutableSymbolFile(
module_spec, search_paths, module_sp->GetSymbolLocatorStatistics());
if (module_spec.GetSourceMappingList().GetSize())
module_sp->GetSourceMappingList().Append(
module_spec.GetSourceMappingList(), true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ SymbolVendorPECOFF::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);
FileSpec dsym_fspec = PluginManager::LocateExecutableSymbolFile(
module_spec, search_paths, module_sp->GetSymbolLocatorStatistics());
if (!dsym_fspec)
return nullptr;

Expand Down
4 changes: 2 additions & 2 deletions lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp,
module_spec.GetSymbolFileSpec() = *symbol_file_spec;

FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
FileSpec sym_fspec =
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
FileSpec sym_fspec = PluginManager::LocateExecutableSymbolFile(
module_spec, search_paths, module_sp->GetSymbolLocatorStatistics());
if (!sym_fspec)
return nullptr;

Expand Down
18 changes: 18 additions & 0 deletions lldb/source/Target/Statistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ json::Value ModuleStats::ToJSON() const {
debug_info_had_incomplete_types);
module.try_emplace("symbolTableStripped", symtab_stripped);
module.try_emplace("symbolTableSymbolCount", symtab_symbol_count);

if (!symbol_locator_time.map.empty()) {
json::Object obj;
for (const auto &entry : symbol_locator_time.map)
obj.try_emplace(entry.first().str(), entry.second);
module.try_emplace("symbolLocatorTime", std::move(obj));
}

if (!symfile_path.empty())
module.try_emplace("symbolFilePath", symfile_path);

Expand Down Expand Up @@ -289,6 +297,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(

json::Array json_targets;
json::Array json_modules;
StatisticsMap symbol_locator_total_time;
double symtab_parse_time = 0.0;
double symtab_index_time = 0.0;
double debug_parse_time = 0.0;
Expand Down Expand Up @@ -319,6 +328,8 @@ llvm::json::Value DebuggerStats::ReportStatistics(
ModuleStats module_stat;
module_stat.symtab_parse_time = module->GetSymtabParseTime().get().count();
module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count();
module_stat.symbol_locator_time = module->GetSymbolLocatorStatistics();
symbol_locator_total_time.merge(module_stat.symbol_locator_time);
Symtab *symtab = module->GetSymtab(/*can_create=*/false);
if (symtab) {
module_stat.symtab_symbol_count = symtab->GetNumSymbols();
Expand Down Expand Up @@ -427,6 +438,13 @@ llvm::json::Value DebuggerStats::ReportStatistics(
global_stats.try_emplace("targets", std::move(json_targets));
}

if (!symbol_locator_total_time.map.empty()) {
json::Object obj;
for (const auto &entry : symbol_locator_total_time.map)
obj.try_emplace(entry.first().str(), entry.second);
global_stats.try_emplace("totalSymbolLocatorTime", std::move(obj));
}

ConstStringStats const_string_stats;
json::Object json_memory{
{"strings", const_string_stats.ToJSON()},
Expand Down
1 change: 0 additions & 1 deletion lldb/test/Shell/Commands/command-statistics-dump.test
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
# CHECK: "modules": [
# CHECK: {
# CHECK: "path": {{.*}}-main.exe
# CHECK-NOT: }

# PRELOAD_TRUE: "symbolTableParseTime":
# PRELOAD_TRUE-SAME: {{[1-9]+}}
Expand Down
6 changes: 4 additions & 2 deletions lldb/unittests/Symbol/LocateSymbolFileTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ TEST_F(
TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
ModuleSpec module_spec;
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
StatisticsMap map;
FileSpec symbol_file_spec =
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths, map);
EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
}

Expand All @@ -41,7 +42,8 @@ TEST_F(SymbolsTest,
module_spec.GetSymbolFileSpec().SetFile(
"4A524676-B24B-4F4E-968A-551D465EBAF1.so", FileSpec::Style::native);
FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
StatisticsMap map;
FileSpec symbol_file_spec =
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
PluginManager::LocateExecutableSymbolFile(module_spec, search_paths, map);
EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
}
Loading