Add symbol locator time for each module in statistics (#137379)
Identical PR to: https://github.com/llvm/llvm-project/pull/134563 Previous PR was approved and landed but broke the build due to bad merge. Manually resolve the merge conflict and try to land again. Co-authored-by: George Hu <georgehuyubo@gmail.com>
This commit is contained in:
parent
3e4e365fac
commit
77f8335a07
@ -885,6 +885,10 @@ public:
|
||||
/// 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"
|
||||
@ -1064,6 +1068,8 @@ protected:
|
||||
/// 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>>
|
||||
|
@ -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"
|
||||
@ -379,11 +380,13 @@ public:
|
||||
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,
|
||||
|
@ -90,6 +90,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// 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()) {}
|
||||
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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() =
|
||||
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
|
@ -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
|
||||
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
@ -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;
|
||||
@ -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();
|
||||
@ -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()},
|
||||
|
@ -23,7 +23,6 @@
|
||||
# CHECK: "modules": [
|
||||
# CHECK: {
|
||||
# CHECK: "path": {{.*}}-main.exe
|
||||
# CHECK-NOT: }
|
||||
|
||||
# PRELOAD_TRUE: "symbolTableParseTime":
|
||||
# PRELOAD_TRUE-SAME: {{[1-9]+}}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
@ -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…
x
Reference in New Issue
Block a user