Author: Wanyi Date: 2024-02-06T19:47:34-05:00 New Revision: 2217837c3377c22bffb6c498a732ce4672b8b535
URL: https://github.com/llvm/llvm-project/commit/2217837c3377c22bffb6c498a732ce4672b8b535 DIFF: https://github.com/llvm/llvm-project/commit/2217837c3377c22bffb6c498a732ce4672b8b535.diff LOG: Support statistics dump summary only mode (#80745) Add a new --summary option to statistics dump command so that it is much more light weight than the full version. Introduce a new SBStatisticsOptions API setting the verbosity of statistics dump. [PR #80218](https://github.com/llvm/llvm-project/pull/80218#discussion_r1473639878) Added: lldb/bindings/interface/SBStatisticsOptionsDocStrings.i lldb/include/lldb/API/SBStatisticsOptions.h lldb/source/API/SBStatisticsOptions.cpp Modified: lldb/bindings/headers.swig lldb/bindings/interfaces.swig lldb/include/lldb/API/LLDB.h lldb/include/lldb/API/SBDefines.h lldb/include/lldb/API/SBTarget.h lldb/include/lldb/Target/Statistics.h lldb/include/lldb/Target/Target.h lldb/include/lldb/lldb-forward.h lldb/source/API/CMakeLists.txt lldb/source/API/SBTarget.cpp lldb/source/Commands/CommandObjectStats.cpp lldb/source/Commands/Options.td lldb/source/Target/Statistics.cpp lldb/source/Target/Target.cpp lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py lldb/test/API/functionalities/stats_api/main.c Removed: ################################################################################ diff --git a/lldb/bindings/headers.swig b/lldb/bindings/headers.swig index 408db90b925f1..e8d0cda288141 100644 --- a/lldb/bindings/headers.swig +++ b/lldb/bindings/headers.swig @@ -54,6 +54,7 @@ #include "lldb/API/SBScriptObject.h" #include "lldb/API/SBSection.h" #include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBStatisticsOptions.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" #include "lldb/API/SBStructuredData.h" diff --git a/lldb/bindings/interface/SBStatisticsOptionsDocStrings.i b/lldb/bindings/interface/SBStatisticsOptionsDocStrings.i new file mode 100644 index 0000000000000..f72cf84319e19 --- /dev/null +++ b/lldb/bindings/interface/SBStatisticsOptionsDocStrings.i @@ -0,0 +1,8 @@ +%feature("docstring", +"A container for options to use when dumping statistics." +) lldb::SBStatisticsOptions; + +%feature("docstring", "Sets whether the statistics should only dump a summary." +) lldb::SBStatisticsOptions::SetSummaryOnly; +%feature("docstring", "Gets whether the statistics only dump a summary." +) lldb::SBStatisticsOptions::GetSummaryOnly; diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig index 9ca479218f621..a31a0b4af1eb6 100644 --- a/lldb/bindings/interfaces.swig +++ b/lldb/bindings/interfaces.swig @@ -56,6 +56,7 @@ %include "./interface/SBReproducerDocstrings.i" %include "./interface/SBSectionDocstrings.i" %include "./interface/SBSourceManagerDocstrings.i" +%include "./interface/SBStatisticsOptionsDocstrings.i" %include "./interface/SBStreamDocstrings.i" %include "./interface/SBStringListDocstrings.i" %include "./interface/SBStructuredDataDocstrings.i" @@ -131,6 +132,7 @@ %include "lldb/API/SBScriptObject.h" %include "lldb/API/SBSection.h" %include "lldb/API/SBSourceManager.h" +%include "lldb/API/SBStatisticsOptions.h" %include "lldb/API/SBStream.h" %include "lldb/API/SBStringList.h" %include "lldb/API/SBStructuredData.h" diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h index f5f1b87a046c2..c83eb92fcfb30 100644 --- a/lldb/include/lldb/API/LLDB.h +++ b/lldb/include/lldb/API/LLDB.h @@ -56,6 +56,7 @@ #include "lldb/API/SBReproducer.h" #include "lldb/API/SBSection.h" #include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBStatisticsOptions.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" #include "lldb/API/SBStructuredData.h" diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index 92d823fa1dfe2..1181920677b46 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -99,6 +99,7 @@ class LLDB_API SBReproducer; class LLDB_API SBScriptObject; class LLDB_API SBSection; class LLDB_API SBSourceManager; +class LLDB_API SBStatisticsOptions; class LLDB_API SBStream; class LLDB_API SBStringList; class LLDB_API SBStructuredData; diff --git a/lldb/include/lldb/API/SBStatisticsOptions.h b/lldb/include/lldb/API/SBStatisticsOptions.h new file mode 100644 index 0000000000000..8019ed4315ca2 --- /dev/null +++ b/lldb/include/lldb/API/SBStatisticsOptions.h @@ -0,0 +1,36 @@ +//===-- SBStatisticsOptions.h -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_API_SBSTATISTICSOPTIONS_H +#define LLDB_API_SBSTATISTICSOPTIONS_H + +#include "lldb/API/SBDefines.h" + +namespace lldb { + +/// This class handles the verbosity when dumping statistics +class LLDB_API SBStatisticsOptions { +public: + SBStatisticsOptions(); + SBStatisticsOptions(const lldb::SBStatisticsOptions &rhs); + ~SBStatisticsOptions(); + + const SBStatisticsOptions &operator=(const lldb::SBStatisticsOptions &rhs); + + void SetSummaryOnly(bool b); + bool GetSummaryOnly(); + +protected: + friend class SBTarget; + const lldb_private::StatisticsOptions &ref() const; + +private: + std::unique_ptr<lldb_private::StatisticsOptions> m_opaque_up; +}; +} // namespace lldb +#endif // LLDB_API_SBSTATISTICSOPTIONS_H diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 83087623088c5..f7bdd3093d202 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -17,6 +17,7 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBFileSpecList.h" #include "lldb/API/SBLaunchInfo.h" +#include "lldb/API/SBStatisticsOptions.h" #include "lldb/API/SBSymbolContextList.h" #include "lldb/API/SBType.h" #include "lldb/API/SBValue.h" @@ -90,6 +91,15 @@ class LLDB_API SBTarget { /// A SBStructuredData with the statistics collected. lldb::SBStructuredData GetStatistics(); + /// Returns a dump of the collected statistics. + /// + /// \param[in] options + /// An objects object that contains all options for the statistics dumping. + /// + /// \return + /// A SBStructuredData with the statistics collected. + lldb::SBStructuredData GetStatistics(SBStatisticsOptions options); + /// Return the platform object associated with the target. /// /// After return, the platform object should be checked for diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h index f672786f58f84..f838fa17f80c2 100644 --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -130,10 +130,15 @@ struct ConstStringStats { ConstString::MemoryStats stats = ConstString::GetMemoryStats(); }; +struct StatisticsOptions { + bool summary_only = false; +}; + /// A class that represents statistics for a since lldb_private::Target. class TargetStats { public: - llvm::json::Value ToJSON(Target &target); + llvm::json::Value ToJSON(Target &target, + const lldb_private::StatisticsOptions &options); void SetLaunchOrAttachTime(); void SetFirstPrivateStopTime(); @@ -171,9 +176,15 @@ class DebuggerStats { /// The single target to emit statistics for if non NULL, otherwise dump /// statistics only for the specified target. /// + /// \param summary_only + /// If true, only report high level summary statistics without + /// targets/modules/breakpoints etc.. details. + /// /// \return /// Returns a JSON value that contains all target metrics. - static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target); + static llvm::json::Value + ReportStatistics(Debugger &debugger, Target *target, + const lldb_private::StatisticsOptions &options); protected: // Collecting stats can be set to true to collect stats that are expensive diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index c37682e2a0385..8f57358981d4d 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -1599,7 +1599,8 @@ class Target : public std::enable_shared_from_this<Target>, /// /// \return /// Returns a JSON value that contains all target metrics. - llvm::json::Value ReportStatistics(); + llvm::json::Value + ReportStatistics(const lldb_private::StatisticsOptions &options); TargetStats &GetStatistics() { return m_stats; } diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index d89ad21512215..10ba921b9dac8 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -298,6 +298,7 @@ struct CompilerContext; struct LineEntry; struct PropertyDefinition; struct ScriptSummaryFormat; +struct StatisticsOptions; struct StringSummaryFormat; template <unsigned N> class StreamBuffer; diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index 7d478ecc7f599..57cc44f764675 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -69,6 +69,7 @@ add_lldb_library(liblldb SHARED ${option_framework} SBScriptObject.cpp SBSection.cpp SBSourceManager.cpp + SBStatisticsOptions.cpp SBStream.cpp SBStringList.cpp SBStructuredData.cpp diff --git a/lldb/source/API/SBStatisticsOptions.cpp b/lldb/source/API/SBStatisticsOptions.cpp new file mode 100644 index 0000000000000..77a7e26a6bd4b --- /dev/null +++ b/lldb/source/API/SBStatisticsOptions.cpp @@ -0,0 +1,49 @@ +//===-- SBStatisticsOptions.cpp -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBStatisticsOptions.h" +#include "lldb/Target/Statistics.h" +#include "lldb/Utility/Instrumentation.h" + +#include "Utils.h" + +using namespace lldb; +using namespace lldb_private; + +SBStatisticsOptions::SBStatisticsOptions() + : m_opaque_up(new StatisticsOptions()) { + LLDB_INSTRUMENT_VA(this); + m_opaque_up->summary_only = false; +} + +SBStatisticsOptions::SBStatisticsOptions(const SBStatisticsOptions &rhs) { + LLDB_INSTRUMENT_VA(this, rhs); + + m_opaque_up = clone(rhs.m_opaque_up); +} + +SBStatisticsOptions::~SBStatisticsOptions() = default; + +const SBStatisticsOptions & +SBStatisticsOptions::operator=(const SBStatisticsOptions &rhs) { + LLDB_INSTRUMENT_VA(this, rhs); + + if (this != &rhs) + m_opaque_up = clone(rhs.m_opaque_up); + return *this; +} + +void SBStatisticsOptions::SetSummaryOnly(bool b) { + m_opaque_up->summary_only = b; +} + +bool SBStatisticsOptions::GetSummaryOnly() { return m_opaque_up->summary_only; } + +const lldb_private::StatisticsOptions &SBStatisticsOptions::ref() const { + return *m_opaque_up; +} diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 8e616afbcb4e8..cc9f1fdd76afa 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -199,15 +199,22 @@ SBDebugger SBTarget::GetDebugger() const { SBStructuredData SBTarget::GetStatistics() { LLDB_INSTRUMENT_VA(this); + SBStatisticsOptions options; + return GetStatistics(options); +} + +SBStructuredData SBTarget::GetStatistics(SBStatisticsOptions options) { + LLDB_INSTRUMENT_VA(this); SBStructuredData data; TargetSP target_sp(GetSP()); if (!target_sp) return data; std::string json_str = - llvm::formatv("{0:2}", - DebuggerStats::ReportStatistics(target_sp->GetDebugger(), - target_sp.get())).str(); + llvm::formatv("{0:2}", DebuggerStats::ReportStatistics( + target_sp->GetDebugger(), target_sp.get(), + options.ref())) + .str(); data.m_impl_up->SetObjectSP(StructuredData::ParseJSON(json_str)); return data; } diff --git a/lldb/source/Commands/CommandObjectStats.cpp b/lldb/source/Commands/CommandObjectStats.cpp index 262de0bda144a..b23b7024c8217 100644 --- a/lldb/source/Commands/CommandObjectStats.cpp +++ b/lldb/source/Commands/CommandObjectStats.cpp @@ -75,6 +75,9 @@ class CommandObjectStatsDump : public CommandObjectParsed { case 'a': m_all_targets = true; break; + case 's': + m_stats_options.summary_only = true; + break; default: llvm_unreachable("Unimplemented option"); } @@ -83,13 +86,17 @@ class CommandObjectStatsDump : public CommandObjectParsed { void OptionParsingStarting(ExecutionContext *execution_context) override { m_all_targets = false; + m_stats_options = StatisticsOptions(); } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { return llvm::ArrayRef(g_statistics_dump_options); } + const StatisticsOptions &GetStatisticsOptions() { return m_stats_options; } + bool m_all_targets = false; + StatisticsOptions m_stats_options = StatisticsOptions(); }; public: @@ -109,7 +116,8 @@ class CommandObjectStatsDump : public CommandObjectParsed { target = m_exe_ctx.GetTargetPtr(); result.AppendMessageWithFormatv( - "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target)); + "{0:2}", DebuggerStats::ReportStatistics( + GetDebugger(), target, m_options.GetStatisticsOptions())); result.SetStatus(eReturnStatusSuccessFinishResult); } diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index ed3167727bcd3..a87f457105aac 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1412,4 +1412,7 @@ let Command = "trace schema" in { let Command = "statistics dump" in { def statistics_dump_all: Option<"all-targets", "a">, Group<1>, Desc<"Include statistics for all targets.">; + def statistics_dump_summary: Option<"summary", "s">, Group<1>, + Desc<"Dump only high-level summary statistics." + "Exclude targets, modules, breakpoints etc... details.">; } diff --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp index 4699710035b2d..ec0a4c84692de 100644 --- a/lldb/source/Target/Statistics.cpp +++ b/lldb/source/Target/Statistics.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/Module.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" @@ -100,60 +101,94 @@ llvm::json::Value ConstStringStats::ToJSON() const { return obj; } -json::Value TargetStats::ToJSON(Target &target) { - CollectStats(target); +json::Value +TargetStats::ToJSON(Target &target, + const lldb_private::StatisticsOptions &options) { + json::Object target_metrics_json; + ProcessSP process_sp = target.GetProcessSP(); + const bool summary_only = options.summary_only; + if (!summary_only) { + CollectStats(target); - json::Array json_module_uuid_array; - for (auto module_identifier : m_module_identifiers) - json_module_uuid_array.emplace_back(module_identifier); + json::Array json_module_uuid_array; + for (auto module_identifier : m_module_identifiers) + json_module_uuid_array.emplace_back(module_identifier); - json::Object target_metrics_json{ - {m_expr_eval.name, m_expr_eval.ToJSON()}, - {m_frame_var.name, m_frame_var.ToJSON()}, - {"moduleIdentifiers", std::move(json_module_uuid_array)}}; + target_metrics_json.try_emplace(m_expr_eval.name, m_expr_eval.ToJSON()); + target_metrics_json.try_emplace(m_frame_var.name, m_frame_var.ToJSON()); + target_metrics_json.try_emplace("moduleIdentifiers", + std::move(json_module_uuid_array)); - if (m_launch_or_attach_time && m_first_private_stop_time) { - double elapsed_time = - elapsed(*m_launch_or_attach_time, *m_first_private_stop_time); - target_metrics_json.try_emplace("launchOrAttachTime", elapsed_time); - } - if (m_launch_or_attach_time && m_first_public_stop_time) { - double elapsed_time = - elapsed(*m_launch_or_attach_time, *m_first_public_stop_time); - target_metrics_json.try_emplace("firstStopTime", elapsed_time); + if (m_launch_or_attach_time && m_first_private_stop_time) { + double elapsed_time = + elapsed(*m_launch_or_attach_time, *m_first_private_stop_time); + target_metrics_json.try_emplace("launchOrAttachTime", elapsed_time); + } + if (m_launch_or_attach_time && m_first_public_stop_time) { + double elapsed_time = + elapsed(*m_launch_or_attach_time, *m_first_public_stop_time); + target_metrics_json.try_emplace("firstStopTime", elapsed_time); + } + target_metrics_json.try_emplace("targetCreateTime", + m_create_time.get().count()); + + json::Array breakpoints_array; + double totalBreakpointResolveTime = 0.0; + // Report both the normal breakpoint list and the internal breakpoint list. + for (int i = 0; i < 2; ++i) { + BreakpointList &breakpoints = target.GetBreakpointList(i == 1); + std::unique_lock<std::recursive_mutex> lock; + breakpoints.GetListMutex(lock); + size_t num_breakpoints = breakpoints.GetSize(); + for (size_t i = 0; i < num_breakpoints; i++) { + Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get(); + breakpoints_array.push_back(bp->GetStatistics()); + totalBreakpointResolveTime += bp->GetResolveTime().count(); + } + } + target_metrics_json.try_emplace("breakpoints", + std::move(breakpoints_array)); + target_metrics_json.try_emplace("totalBreakpointResolveTime", + totalBreakpointResolveTime); + + if (process_sp) { + UnixSignalsSP unix_signals_sp = process_sp->GetUnixSignals(); + if (unix_signals_sp) + target_metrics_json.try_emplace( + "signals", unix_signals_sp->GetHitCountStatistics()); + } } - target_metrics_json.try_emplace("targetCreateTime", - m_create_time.get().count()); - - json::Array breakpoints_array; - double totalBreakpointResolveTime = 0.0; - // Rport both the normal breakpoint list and the internal breakpoint list. - for (int i = 0; i < 2; ++i) { - BreakpointList &breakpoints = target.GetBreakpointList(i == 1); + + // Counting "totalSharedLibraryEventHitCount" from breakpoints of kind + // "shared-library-event". + { + uint32_t shared_library_event_breakpoint_hit_count = 0; + // The "shared-library-event" is only found in the internal breakpoint list. + BreakpointList &breakpoints = target.GetBreakpointList(/* internal */ true); std::unique_lock<std::recursive_mutex> lock; breakpoints.GetListMutex(lock); size_t num_breakpoints = breakpoints.GetSize(); for (size_t i = 0; i < num_breakpoints; i++) { Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get(); - breakpoints_array.push_back(bp->GetStatistics()); - totalBreakpointResolveTime += bp->GetResolveTime().count(); + if (strcmp(bp->GetBreakpointKind(), "shared-library-event") == 0) + shared_library_event_breakpoint_hit_count += bp->GetHitCount(); } + + target_metrics_json.try_emplace("totalSharedLibraryEventHitCount", + shared_library_event_breakpoint_hit_count); } - ProcessSP process_sp = target.GetProcessSP(); if (process_sp) { - UnixSignalsSP unix_signals_sp = process_sp->GetUnixSignals(); - if (unix_signals_sp) - target_metrics_json.try_emplace("signals", - unix_signals_sp->GetHitCountStatistics()); uint32_t stop_id = process_sp->GetStopID(); target_metrics_json.try_emplace("stopCount", stop_id); - } - target_metrics_json.try_emplace("breakpoints", std::move(breakpoints_array)); - target_metrics_json.try_emplace("totalBreakpointResolveTime", - totalBreakpointResolveTime); - target_metrics_json.try_emplace("sourceMapDeduceCount", m_source_map_deduce_count); + llvm::StringRef dyld_plugin_name; + if (process_sp->GetDynamicLoader()) + dyld_plugin_name = process_sp->GetDynamicLoader()->GetPluginName(); + target_metrics_json.try_emplace("dyldPluginName", dyld_plugin_name); + } + target_metrics_json.try_emplace("sourceMapDeduceCount", + m_source_map_deduce_count); return target_metrics_json; } @@ -184,8 +219,12 @@ void TargetStats::IncreaseSourceMapDeduceCount() { bool DebuggerStats::g_collecting_stats = false; -llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, - Target *target) { +llvm::json::Value DebuggerStats::ReportStatistics( + Debugger &debugger, Target *target, + const lldb_private::StatisticsOptions &options) { + + const bool summary_only = options.summary_only; + json::Array json_targets; json::Array json_modules; double symtab_parse_time = 0.0; @@ -197,12 +236,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, uint32_t debug_index_loaded = 0; uint32_t debug_index_saved = 0; uint64_t debug_info_size = 0; - if (target) { - json_targets.emplace_back(target->ReportStatistics()); - } else { - for (const auto &target : debugger.GetTargetList().Targets()) - json_targets.emplace_back(target->ReportStatistics()); - } + std::vector<ModuleStats> modules; std::lock_guard<std::recursive_mutex> guard( Module::GetAllocationModuleCollectionMutex()); @@ -215,15 +249,6 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { Module *module = Module::GetAllocatedModuleAtIndex(image_idx); ModuleStats module_stat; - module_stat.identifier = (intptr_t)module; - module_stat.path = module->GetFileSpec().GetPath(); - if (ConstString object_name = module->GetObjectName()) { - module_stat.path.append(1, '('); - module_stat.path.append(object_name.GetStringRef().str()); - module_stat.path.append(1, ')'); - } - module_stat.uuid = module->GetUUID().GetAsString(); - module_stat.triple = module->GetArchitecture().GetTriple().str(); module_stat.symtab_parse_time = module->GetSymtabParseTime().get().count(); module_stat.symtab_index_time = module->GetSymtabIndexTime().get().count(); Symtab *symtab = module->GetSymtab(); @@ -237,13 +262,14 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, } SymbolFile *sym_file = module->GetSymbolFile(); if (sym_file) { - - if (sym_file->GetObjectFile() != module->GetObjectFile()) - module_stat.symfile_path = - sym_file->GetObjectFile()->GetFileSpec().GetPath(); - module_stat.debug_index_time = sym_file->GetDebugInfoIndexTime().count(); - module_stat.debug_parse_time = sym_file->GetDebugInfoParseTime().count(); - module_stat.debug_info_size = sym_file->GetDebugInfoSize(); + if (!summary_only) { + if (sym_file->GetObjectFile() != module->GetObjectFile()) + module_stat.symfile_path = + sym_file->GetObjectFile()->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()); + } module_stat.debug_info_index_loaded_from_cache = sym_file->GetDebugInfoIndexWasLoadedFromCache(); if (module_stat.debug_info_index_loaded_from_cache) @@ -252,9 +278,9 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, sym_file->GetDebugInfoIndexWasSavedToCache(); if (module_stat.debug_info_index_saved_to_cache) ++debug_index_saved; - 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()); + module_stat.debug_index_time = sym_file->GetDebugInfoIndexTime().count(); + module_stat.debug_parse_time = sym_file->GetDebugInfoParseTime().count(); + module_stat.debug_info_size = sym_file->GetDebugInfoSize(); module_stat.symtab_stripped = module->GetObjectFile()->IsStripped(); if (module_stat.symtab_stripped) ++num_stripped_modules; @@ -284,21 +310,21 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, if (module_stat.debug_info_had_incomplete_types) ++num_modules_with_incomplete_types; - json_modules.emplace_back(module_stat.ToJSON()); + if (!summary_only) { + module_stat.identifier = (intptr_t)module; + module_stat.path = module->GetFileSpec().GetPath(); + if (ConstString object_name = module->GetObjectName()) { + module_stat.path.append(1, '('); + module_stat.path.append(object_name.GetStringRef().str()); + module_stat.path.append(1, ')'); + } + module_stat.uuid = module->GetUUID().GetAsString(); + module_stat.triple = module->GetArchitecture().GetTriple().str(); + json_modules.emplace_back(module_stat.ToJSON()); + } } - ConstStringStats const_string_stats; - json::Object json_memory{ - {"strings", const_string_stats.ToJSON()}, - }; - - json::Value cmd_stats = debugger.GetCommandInterpreter().GetStatistics(); - json::Object global_stats{ - {"targets", std::move(json_targets)}, - {"modules", std::move(json_modules)}, - {"memory", std::move(json_memory)}, - {"commands", std::move(cmd_stats)}, {"totalSymbolTableParseTime", symtab_parse_time}, {"totalSymbolTableIndexTime", symtab_index_time}, {"totalSymbolTablesLoadedFromCache", symtabs_loaded}, @@ -316,5 +342,25 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, {"totalDebugInfoEnabled", num_debug_info_enabled_modules}, {"totalSymbolTableStripped", num_stripped_modules}, }; + + if (target) { + json_targets.emplace_back(target->ReportStatistics(options)); + } else { + for (const auto &target : debugger.GetTargetList().Targets()) + json_targets.emplace_back(target->ReportStatistics(options)); + } + global_stats.try_emplace("targets", std::move(json_targets)); + + if (!summary_only) { + ConstStringStats const_string_stats; + json::Object json_memory{ + {"strings", const_string_stats.ToJSON()}, + }; + json::Value cmd_stats = debugger.GetCommandInterpreter().GetStatistics(); + global_stats.try_emplace("modules", std::move(json_modules)); + global_stats.try_emplace("memory", std::move(json_memory)); + global_stats.try_emplace("commands", std::move(cmd_stats)); + } + return std::move(global_stats); } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index e969340fdf1eb..e17bfcb5d5e2a 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -4962,4 +4962,7 @@ std::recursive_mutex &Target::GetAPIMutex() { } /// Get metrics associated with this target in JSON format. -llvm::json::Value Target::ReportStatistics() { return m_stats.ToJSON(*this); } +llvm::json::Value +Target::ReportStatistics(const lldb_private::StatisticsOptions &options) { + return m_stats.ToJSON(*this, options); +} diff --git a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py index fe55922fe4c31..457a2022fe4b8 100644 --- a/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py +++ b/lldb/test/API/functionalities/stats_api/TestStatisticsAPI.py @@ -16,7 +16,10 @@ def test_stats_api(self): """ self.build() exe = self.getBuildArtifact("a.out") - target = self.dbg.CreateTarget(exe) + # Launch a process and break + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.c") + ) # Test enabling/disabling stats self.assertFalse(target.GetCollectingStats()) @@ -74,6 +77,24 @@ def test_stats_api(self): 'Make sure the "failures" key in in "frameVariable" dictionary"', ) + # Test statistics summary. + stats_options = lldb.SBStatisticsOptions() + stats_options.SetSummaryOnly(True) + stats_summary = target.GetStatistics(stats_options) + stream_summary = lldb.SBStream() + stats_summary.GetAsJSON(stream_summary) + debug_stats_summary = json.loads(stream_summary.GetData()) + self.assertNotIn("modules", debug_stats_summary) + self.assertNotIn("memory", debug_stats_summary) + self.assertNotIn("commands", debug_stats_summary) + + # Summary values should be the same as in full statistics. + # Except the parse time on Mac OS X is not deterministic. + for key, value in debug_stats_summary.items(): + self.assertIn(key, debug_stats) + if key != "targets" and not key.endswith("Time"): + self.assertEqual(debug_stats[key], value) + def test_command_stats_api(self): """ Test GetCommandInterpreter::GetStatistics() API. diff --git a/lldb/test/API/functionalities/stats_api/main.c b/lldb/test/API/functionalities/stats_api/main.c index 03b2213bb9a36..02fea2eb75ff0 100644 --- a/lldb/test/API/functionalities/stats_api/main.c +++ b/lldb/test/API/functionalities/stats_api/main.c @@ -1,3 +1,3 @@ int main(void) { - return 0; + return 0; // break here } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits