Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions lldb/include/lldb/API/SBDebugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ class LLDB_API SBDebugger {

SBTypeSynthetic GetSyntheticForType(SBTypeNameSpecifier);

void ResetStatistics();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a header doc comment for this to document what this will do:

  • clear all stats for all modules in all targets
  • clear all target breakpoint stats?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments added. I do not think we need to clear any breakpoint stats because they are not reused across debug sessions by "reuse lldb-dap"


#ifndef SWIG
/// Run the command interpreter.
///
Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/API/SBTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class LLDB_API SBTarget {
/// A SBStructuredData with the statistics collected.
lldb::SBStructuredData GetStatistics(SBStatisticsOptions options);

/// Reset the statistics collected for this target.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document this a bit better with more explanation

void ResetStatistics();

/// Return the platform object associated with the target.
///
/// After return, the platform object should be checked for
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,8 @@ class Module : public std::enable_shared_from_this<Module>,
/// ElapsedTime RAII object.
StatsDuration &GetSymtabIndexTime() { return m_symtab_index_time; }

void ResetStatistics();

/// \class LookupInfo Module.h "lldb/Core/Module.h"
/// A class that encapsulates name lookup information.
///
Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/Symbol/SymbolFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,9 @@ class SymbolFile : public PluginInterface {
/// hasn't been indexed yet, or a valid duration if it has.
virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; }

/// Reset the statistics for the symbol file.
virtual void ResetStatistics() {}

/// Get the additional modules that this symbol file uses to parse debug info.
///
/// Some debug info is stored in stand alone object files that are represented
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/SymbolFileOnDemand.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override;
lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;

void ResetStatistics() override;

uint32_t GetAbilities() override;

Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); }
Expand Down
12 changes: 12 additions & 0 deletions lldb/include/lldb/Target/Statistics.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class StatsDuration {
}
operator Duration() const { return get(); }

void reset() { value.store(0, std::memory_order_relaxed); }

StatsDuration &operator+=(Duration dur) {
value.fetch_add(std::chrono::duration_cast<InternalDuration>(dur).count(),
std::memory_order_relaxed);
Expand Down Expand Up @@ -311,6 +313,16 @@ class DebuggerStats {
ReportStatistics(Debugger &debugger, Target *target,
const lldb_private::StatisticsOptions &options);

/// Reset metrics associated with one or all targets in a debugger.
///
/// \param debugger
/// The debugger to reset the target list from if \a target is NULL.
///
/// \param target
/// The target to reset statistics for, or if null, reset statistics
/// for all targets
static void ResetStatistics(Debugger &debugger, Target *target);

protected:
// Collecting stats can be set to true to collect stats that are expensive
// to collect. By default all stats that are cheap to collect are enabled.
Expand Down
6 changes: 6 additions & 0 deletions lldb/source/API/SBDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1667,6 +1667,12 @@ SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) {
DataVisualization::GetSyntheticForType(type_name.GetSP()));
}

void SBDebugger::ResetStatistics() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a void SBTarget::ResetStatistics() too that calls with the right target?

LLDB_INSTRUMENT_VA(this);
if (m_opaque_sp)
DebuggerStats::ResetStatistics(*m_opaque_sp, nullptr);
}

static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) {
if (categories == nullptr)
return {};
Expand Down
7 changes: 7 additions & 0 deletions lldb/source/API/SBTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ SBStructuredData SBTarget::GetStatistics(SBStatisticsOptions options) {
return data;
}

void SBTarget::ResetStatistics() {
LLDB_INSTRUMENT_VA(this);
TargetSP target_sp(GetSP());
if (target_sp)
DebuggerStats::ResetStatistics(target_sp->GetDebugger(), target_sp.get());
}

void SBTarget::SetCollectingStats(bool v) {
LLDB_INSTRUMENT_VA(this, v);

Expand Down
9 changes: 9 additions & 0 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,15 @@ bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
return SetArchitecture(merged_arch);
}

void Module::ResetStatistics() {
m_symtab_parse_time.reset();
m_symtab_index_time.reset();
SymbolFile *sym_file = GetSymbolFile();
if (sym_file) {
sym_file->ResetStatistics();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove braces from single line "if" statement per llvm coding guidelines

}

llvm::VersionTuple Module::GetVersion() {
if (ObjectFile *obj_file = GetObjectFile())
return obj_file->GetVersion();
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class DWARFIndex {

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

void ResetStatistics() { m_index_time.reset(); }

protected:
Module &m_module;
StatsDuration m_index_time;
Expand Down
6 changes: 6 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4464,6 +4464,12 @@ StatsDuration::Duration SymbolFileDWARF::GetDebugInfoIndexTime() {
return {};
}

void SymbolFileDWARF::ResetStatistics() {
m_parse_time.reset();
if (m_index)
return m_index->ResetStatistics();
}

Status SymbolFileDWARF::CalculateFrameVariableError(StackFrame &frame) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
CompileUnit *cu = frame.GetSymbolContext(eSymbolContextCompUnit).comp_unit;
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ class SymbolFileDWARF : public SymbolFileCommon {

StatsDuration &GetDebugInfoParseTimeRef() { return m_parse_time; }

void ResetStatistics() override;

virtual lldb::offset_t
GetVendorDWARFOpcodeSize(const DataExtractor &data,
const lldb::offset_t data_offset,
Expand Down
6 changes: 6 additions & 0 deletions lldb/source/Symbol/SymbolFileOnDemand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,12 @@ StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() {
return m_sym_file_impl->GetDebugInfoIndexTime();
}

void SymbolFileOnDemand::ResetStatistics() {
LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(),
__FUNCTION__);
return m_sym_file_impl->ResetStatistics();
}

void SymbolFileOnDemand::SetLoadDebugInfoEnabled() {
if (m_debug_info_enabled)
return;
Expand Down
24 changes: 22 additions & 2 deletions lldb/source/Target/Statistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,22 @@ void TargetStats::IncreaseSourceRealpathCompatibleCount(uint32_t count) {

bool DebuggerStats::g_collecting_stats = false;

void DebuggerStats::ResetStatistics(Debugger &debugger, Target *target) {
std::lock_guard<std::recursive_mutex> guard(
Module::GetAllocationModuleCollectionMutex());
const uint64_t num_modules = target != nullptr
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to lock the Module::GetAllocationModuleCollectionMutex() when using the Module static calls for the global module list.

? target->GetImages().GetSize()
: Module::GetNumberAllocatedModules();
for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
Module *module = target != nullptr
? target->GetImages().GetModuleAtIndex(image_idx).get()
: Module::GetAllocatedModuleAtIndex(image_idx);
if (module == nullptr)
continue;
module->ResetStatistics();
}
}

llvm::json::Value DebuggerStats::ReportStatistics(
Debugger &debugger, Target *target,
const lldb_private::StatisticsOptions &options) {
Expand All @@ -261,14 +277,18 @@ llvm::json::Value DebuggerStats::ReportStatistics(
std::vector<ModuleStats> modules;
std::lock_guard<std::recursive_mutex> guard(
Module::GetAllocationModuleCollectionMutex());
const uint64_t num_modules = Module::GetNumberAllocatedModules();
const uint64_t num_modules = target != nullptr
? target->GetImages().GetSize()
: Module::GetNumberAllocatedModules();
uint32_t num_debug_info_enabled_modules = 0;
uint32_t num_modules_has_debug_info = 0;
uint32_t num_modules_with_variable_errors = 0;
uint32_t num_modules_with_incomplete_types = 0;
uint32_t num_stripped_modules = 0;
for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
Module *module = target != nullptr
? target->GetImages().GetModuleAtIndex(image_idx).get()
: Module::GetAllocatedModuleAtIndex(image_idx);
ModuleStats module_stat;
module_stat.symtab_parse_time = module->GetSymtabParseTime().get().count();
module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count();
Expand Down
40 changes: 38 additions & 2 deletions lldb/test/API/commands/statistics/basic/TestStats.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import lldb
import json
import os
import re

import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
Expand Down Expand Up @@ -540,7 +541,7 @@ def test_no_dsym_binary_has_symfile_identifiers_in_stats(self):
# in the stats.
self.runCmd("b main.cpp:7")

debug_stats = self.get_stats()
debug_stats = self.get_stats("--all-targets")

exe_stats = self.find_module_in_metrics(exe, debug_stats)
# If we don't have a dSYM file, there should not be a key/value pair in
Expand Down Expand Up @@ -986,3 +987,38 @@ def test_summary_statistics_providers_vec(self):
# We may hit the std::vector C++ provider, or a summary provider string
if "c++" in summary_provider_str:
self.assertIn("std::vector", summary_provider_str)

@skipIfWindows
def test_multiple_targets(self):
"""
Test statistics dump only reports the stats from current target and
"statistics dump --all-targets" includes all target stats.
"""
da = {"CXX_SOURCES": "main.cpp", "EXE": self.getBuildArtifact("a.out")}
self.build(dictionary=da)
self.addTearDownCleanup(dictionary=da)

db = {"CXX_SOURCES": "second.cpp", "EXE": self.getBuildArtifact("second.out")}
self.build(dictionary=db)
self.addTearDownCleanup(dictionary=db)

main_exe = self.getBuildArtifact("a.out")
second_exe = self.getBuildArtifact("second.out")

(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
self, "// break here", lldb.SBFileSpec("main.cpp"), None, "a.out"
)
debugger_stats1 = self.get_stats()
self.assertIsNotNone(self.find_module_in_metrics(main_exe, debugger_stats1))
self.assertIsNone(self.find_module_in_metrics(second_exe, debugger_stats1))

(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
self, "// break here", lldb.SBFileSpec("second.cpp"), None, "second.out"
)
debugger_stats2 = self.get_stats()
self.assertIsNone(self.find_module_in_metrics(main_exe, debugger_stats2))
self.assertIsNotNone(self.find_module_in_metrics(second_exe, debugger_stats2))

all_targets_stats = self.get_stats("--all-targets")
self.assertIsNotNone(self.find_module_in_metrics(main_exe, all_targets_stats))
self.assertIsNotNone(self.find_module_in_metrics(second_exe, all_targets_stats))
5 changes: 5 additions & 0 deletions lldb/test/API/commands/statistics/basic/second.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Test that the lldb command `statistics` works.

int main(void) {
return 0; // break here
}
Loading