Skip to content

Commit debd58e

Browse files
author
jeffreytan81
committed
Report statistics per target
1 parent 61a4678 commit debd58e

File tree

13 files changed

+123
-4
lines changed

13 files changed

+123
-4
lines changed

lldb/include/lldb/API/SBDebugger.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ class LLDB_API SBDebugger {
426426

427427
SBTypeSynthetic GetSyntheticForType(SBTypeNameSpecifier);
428428

429+
void ResetStatistics();
430+
429431
#ifndef SWIG
430432
/// Run the command interpreter.
431433
///

lldb/include/lldb/Symbol/SymbolFile.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,13 @@ class SymbolFile : public PluginInterface {
422422
/// hasn't been indexed yet, or a valid duration if it has.
423423
virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; }
424424

425+
/// Reset the time taken to parse the debug information.
426+
virtual void ResetDebugInfoParseTime() {}
427+
428+
/// Reset the time it took to index the debug information in the object
429+
/// file.
430+
virtual void ResetDebugInfoIndexTime() {}
431+
425432
/// Get the additional modules that this symbol file uses to parse debug info.
426433
///
427434
/// Some debug info is stored in stand alone object files that are represented

lldb/include/lldb/Symbol/SymbolFileOnDemand.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
182182
lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override;
183183
lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;
184184

185+
void ResetDebugInfoParseTime() override;
186+
void ResetDebugInfoIndexTime() override;
187+
185188
uint32_t GetAbilities() override;
186189

187190
Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); }

lldb/include/lldb/Target/Statistics.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class StatsDuration {
4141
}
4242
operator Duration() const { return get(); }
4343

44+
void reset() { value.store(0, std::memory_order_relaxed); }
45+
4446
StatsDuration &operator+=(Duration dur) {
4547
value.fetch_add(std::chrono::duration_cast<InternalDuration>(dur).count(),
4648
std::memory_order_relaxed);
@@ -311,6 +313,16 @@ class DebuggerStats {
311313
ReportStatistics(Debugger &debugger, Target *target,
312314
const lldb_private::StatisticsOptions &options);
313315

316+
/// Reset metrics associated with one or all targets in a debugger.
317+
///
318+
/// \param debugger
319+
/// The debugger to reset the target list from if \a target is NULL.
320+
///
321+
/// \param target
322+
/// The target to reset statistics for, or if null, reset statistics
323+
/// for all targets
324+
static void ResetStatistics(Debugger &debugger, Target *target);
325+
314326
protected:
315327
// Collecting stats can be set to true to collect stats that are expensive
316328
// to collect. By default all stats that are cheap to collect are enabled.

lldb/source/API/SBDebugger.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,6 +1667,12 @@ SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) {
16671667
DataVisualization::GetSyntheticForType(type_name.GetSP()));
16681668
}
16691669

1670+
void SBDebugger::ResetStatistics() {
1671+
LLDB_INSTRUMENT_VA(this);
1672+
if (m_opaque_sp)
1673+
DebuggerStats::ResetStatistics(*m_opaque_sp, nullptr);
1674+
}
1675+
16701676
static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) {
16711677
if (categories == nullptr)
16721678
return {};

lldb/source/Core/Debugger.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ void Debugger::Destroy(DebuggerSP &debugger_sp) {
789789
(*debugger_sp->GetAsyncErrorStream()) << result.GetErrorData() << '\n';
790790
}
791791

792+
DebuggerStats::ResetStatistics(*debugger_sp, nullptr);
792793
debugger_sp->Clear();
793794

794795
if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {

lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class DWARFIndex {
8383

8484
StatsDuration::Duration GetIndexTime() { return m_index_time; }
8585

86+
void ResetIndexTime() { m_index_time.reset(); }
87+
8688
protected:
8789
Module &m_module;
8890
StatsDuration m_index_time;

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4464,6 +4464,11 @@ StatsDuration::Duration SymbolFileDWARF::GetDebugInfoIndexTime() {
44644464
return {};
44654465
}
44664466

4467+
void SymbolFileDWARF::ResetDebugInfoIndexTime() {
4468+
if (m_index)
4469+
return m_index->ResetIndexTime();
4470+
}
4471+
44674472
Status SymbolFileDWARF::CalculateFrameVariableError(StackFrame &frame) {
44684473
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
44694474
CompileUnit *cu = frame.GetSymbolContext(eSymbolContextCompUnit).comp_unit;

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ class SymbolFileDWARF : public SymbolFileCommon {
318318

319319
StatsDuration &GetDebugInfoParseTimeRef() { return m_parse_time; }
320320

321+
void ResetDebugInfoParseTime() override { m_parse_time.reset(); }
322+
void ResetDebugInfoIndexTime() override;
323+
321324
virtual lldb::offset_t
322325
GetVendorDWARFOpcodeSize(const DataExtractor &data,
323326
const lldb::offset_t data_offset,

lldb/source/Symbol/SymbolFileOnDemand.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,18 @@ StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() {
555555
return m_sym_file_impl->GetDebugInfoIndexTime();
556556
}
557557

558+
void SymbolFileOnDemand::ResetDebugInfoParseTime() {
559+
LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
560+
__FUNCTION__);
561+
return m_sym_file_impl->ResetDebugInfoParseTime();
562+
}
563+
564+
void SymbolFileOnDemand::ResetDebugInfoIndexTime() {
565+
LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
566+
__FUNCTION__);
567+
return m_sym_file_impl->ResetDebugInfoIndexTime();
568+
}
569+
558570
void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
559571
if (m_debug_info_enabled)
560572
return;

lldb/source/Target/Statistics.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,27 @@ void TargetStats::IncreaseSourceRealpathCompatibleCount(uint32_t count) {
236236

237237
bool DebuggerStats::g_collecting_stats = false;
238238

239+
void DebuggerStats::ResetStatistics(Debugger &debugger, Target *target) {
240+
const uint64_t num_modules = target != nullptr
241+
? target->GetImages().GetSize()
242+
: Module::GetNumberAllocatedModules();
243+
for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
244+
Module *module = target != nullptr
245+
? target->GetImages().GetModuleAtIndex(image_idx).get()
246+
: Module::GetAllocatedModuleAtIndex(image_idx);
247+
if (module == nullptr)
248+
continue;
249+
ModuleStats module_stat;
250+
module->GetSymtabParseTime().reset();
251+
module->GetSymtabIndexTime().reset();
252+
SymbolFile *sym_file = module->GetSymbolFile();
253+
if (sym_file) {
254+
sym_file->ResetDebugInfoIndexTime();
255+
sym_file->ResetDebugInfoParseTime();
256+
}
257+
}
258+
}
259+
239260
llvm::json::Value DebuggerStats::ReportStatistics(
240261
Debugger &debugger, Target *target,
241262
const lldb_private::StatisticsOptions &options) {
@@ -261,14 +282,18 @@ llvm::json::Value DebuggerStats::ReportStatistics(
261282
std::vector<ModuleStats> modules;
262283
std::lock_guard<std::recursive_mutex> guard(
263284
Module::GetAllocationModuleCollectionMutex());
264-
const uint64_t num_modules = Module::GetNumberAllocatedModules();
285+
const uint64_t num_modules = target != nullptr
286+
? target->GetImages().GetSize()
287+
: Module::GetNumberAllocatedModules();
265288
uint32_t num_debug_info_enabled_modules = 0;
266289
uint32_t num_modules_has_debug_info = 0;
267290
uint32_t num_modules_with_variable_errors = 0;
268291
uint32_t num_modules_with_incomplete_types = 0;
269292
uint32_t num_stripped_modules = 0;
270293
for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
271-
Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
294+
Module *module = target != nullptr
295+
? target->GetImages().GetModuleAtIndex(image_idx).get()
296+
: Module::GetAllocatedModuleAtIndex(image_idx);
272297
ModuleStats module_stat;
273298
module_stat.symtab_parse_time = module->GetSymtabParseTime().get().count();
274299
module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count();

lldb/test/API/commands/statistics/basic/TestStats.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import lldb
21
import json
32
import os
43
import re
4+
5+
import lldb
56
from lldbsuite.test.decorators import *
67
from lldbsuite.test.lldbtest import *
78
from lldbsuite.test import lldbutil
@@ -540,7 +541,7 @@ def test_no_dsym_binary_has_symfile_identifiers_in_stats(self):
540541
# in the stats.
541542
self.runCmd("b main.cpp:7")
542543

543-
debug_stats = self.get_stats()
544+
debug_stats = self.get_stats("--all-targets")
544545

545546
exe_stats = self.find_module_in_metrics(exe, debug_stats)
546547
# If we don't have a dSYM file, there should not be a key/value pair in
@@ -986,3 +987,38 @@ def test_summary_statistics_providers_vec(self):
986987
# We may hit the std::vector C++ provider, or a summary provider string
987988
if "c++" in summary_provider_str:
988989
self.assertIn("std::vector", summary_provider_str)
990+
991+
@skipIfWindows
992+
def test_multiple_targets(self):
993+
"""
994+
Test statistics dump only reports the stats from current target and
995+
"statistics dump --all-targets" includes all target stats.
996+
"""
997+
da = {"CXX_SOURCES": "main.cpp", "EXE": self.getBuildArtifact("a.out")}
998+
self.build(dictionary=da)
999+
self.addTearDownCleanup(dictionary=da)
1000+
1001+
db = {"CXX_SOURCES": "second.cpp", "EXE": self.getBuildArtifact("second.out")}
1002+
self.build(dictionary=db)
1003+
self.addTearDownCleanup(dictionary=db)
1004+
1005+
main_exe = self.getBuildArtifact("a.out")
1006+
second_exe = self.getBuildArtifact("second.out")
1007+
1008+
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
1009+
self, "// break here", lldb.SBFileSpec("main.cpp"), None, "a.out"
1010+
)
1011+
debugger_stats1 = self.get_stats()
1012+
self.assertIsNotNone(self.find_module_in_metrics(main_exe, debugger_stats1))
1013+
self.assertIsNone(self.find_module_in_metrics(second_exe, debugger_stats1))
1014+
1015+
(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
1016+
self, "// break here", lldb.SBFileSpec("second.cpp"), None, "second.out"
1017+
)
1018+
debugger_stats2 = self.get_stats()
1019+
self.assertIsNone(self.find_module_in_metrics(main_exe, debugger_stats2))
1020+
self.assertIsNotNone(self.find_module_in_metrics(second_exe, debugger_stats2))
1021+
1022+
all_targets_stats = self.get_stats("--all-targets")
1023+
self.assertIsNotNone(self.find_module_in_metrics(main_exe, all_targets_stats))
1024+
self.assertIsNotNone(self.find_module_in_metrics(second_exe, all_targets_stats))
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Test that the lldb command `statistics` works.
2+
3+
int main(void) {
4+
return 0; // break here
5+
}

0 commit comments

Comments
 (0)