182 lines · cpp
1//===-- CommandObjectStats.cpp --------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "CommandObjectStats.h"10#include "lldb/Core/Debugger.h"11#include "lldb/Host/OptionParser.h"12#include "lldb/Interpreter/CommandInterpreter.h"13#include "lldb/Interpreter/CommandOptionArgumentTable.h"14#include "lldb/Interpreter/CommandReturnObject.h"15#include "lldb/Interpreter/OptionArgParser.h"16#include "lldb/Target/Target.h"17 18using namespace lldb;19using namespace lldb_private;20 21class CommandObjectStatsEnable : public CommandObjectParsed {22public:23 CommandObjectStatsEnable(CommandInterpreter &interpreter)24 : CommandObjectParsed(interpreter, "enable",25 "Enable statistics collection", nullptr,26 eCommandProcessMustBePaused) {}27 28 ~CommandObjectStatsEnable() override = default;29 30protected:31 void DoExecute(Args &command, CommandReturnObject &result) override {32 if (DebuggerStats::GetCollectingStats()) {33 result.AppendError("statistics already enabled");34 return;35 }36 37 DebuggerStats::SetCollectingStats(true);38 result.SetStatus(eReturnStatusSuccessFinishResult);39 }40};41 42class CommandObjectStatsDisable : public CommandObjectParsed {43public:44 CommandObjectStatsDisable(CommandInterpreter &interpreter)45 : CommandObjectParsed(interpreter, "disable",46 "Disable statistics collection", nullptr,47 eCommandProcessMustBePaused) {}48 49 ~CommandObjectStatsDisable() override = default;50 51protected:52 void DoExecute(Args &command, CommandReturnObject &result) override {53 if (!DebuggerStats::GetCollectingStats()) {54 result.AppendError("need to enable statistics before disabling them");55 return;56 }57 58 DebuggerStats::SetCollectingStats(false);59 result.SetStatus(eReturnStatusSuccessFinishResult);60 }61};62 63#define LLDB_OPTIONS_statistics_dump64#include "CommandOptions.inc"65 66class CommandObjectStatsDump : public CommandObjectParsed {67 class CommandOptions : public Options {68 public:69 CommandOptions() { OptionParsingStarting(nullptr); }70 71 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,72 ExecutionContext *execution_context) override {73 Status error;74 const int short_option = m_getopt_table[option_idx].val;75 76 switch (short_option) {77 case 'a':78 m_all_targets = true;79 break;80 case 's':81 m_stats_options.SetSummaryOnly(true);82 break;83 case 'f':84 m_stats_options.SetLoadAllDebugInfo(true);85 break;86 case 'r':87 if (llvm::Expected<bool> bool_or_error =88 OptionArgParser::ToBoolean("--targets", option_arg))89 m_stats_options.SetIncludeTargets(*bool_or_error);90 else91 error = Status::FromError(bool_or_error.takeError());92 break;93 case 'm':94 if (llvm::Expected<bool> bool_or_error =95 OptionArgParser::ToBoolean("--modules", option_arg))96 m_stats_options.SetIncludeModules(*bool_or_error);97 else98 error = Status::FromError(bool_or_error.takeError());99 break;100 case 't':101 if (llvm::Expected<bool> bool_or_error =102 OptionArgParser::ToBoolean("--transcript", option_arg))103 m_stats_options.SetIncludeTranscript(*bool_or_error);104 else105 error = Status::FromError(bool_or_error.takeError());106 break;107 case 'p':108 if (llvm::Expected<bool> bool_or_error =109 OptionArgParser::ToBoolean("--plugins", option_arg))110 m_stats_options.SetIncludePlugins(*bool_or_error);111 else112 error = Status::FromError(bool_or_error.takeError());113 break;114 default:115 llvm_unreachable("Unimplemented option");116 }117 return error;118 }119 120 void OptionParsingStarting(ExecutionContext *execution_context) override {121 m_all_targets = false;122 m_stats_options = StatisticsOptions();123 }124 125 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {126 return llvm::ArrayRef(g_statistics_dump_options);127 }128 129 const StatisticsOptions &GetStatisticsOptions() { return m_stats_options; }130 131 bool m_all_targets = false;132 StatisticsOptions m_stats_options = StatisticsOptions();133 };134 135public:136 CommandObjectStatsDump(CommandInterpreter &interpreter)137 : CommandObjectParsed(138 interpreter, "statistics dump", "Dump metrics in JSON format",139 "statistics dump [<options>]", eCommandRequiresTarget) {}140 141 ~CommandObjectStatsDump() override = default;142 143 Options *GetOptions() override { return &m_options; }144 145protected:146 void DoExecute(Args &command, CommandReturnObject &result) override {147 Target *target = nullptr;148 if (!m_options.m_all_targets)149 target = m_exe_ctx.GetTargetPtr();150 151 // Check if transcript is requested but transcript saving is disabled152 const StatisticsOptions &stats_options = m_options.GetStatisticsOptions();153 if (stats_options.GetIncludeTranscript() &&154 !GetDebugger().GetCommandInterpreter().GetSaveTranscript()) {155 result.AppendWarning(156 "transcript requested but none was saved. Enable with "157 "'settings set interpreter.save-transcript true'");158 }159 160 result.AppendMessageWithFormatv(161 "{0:2}",162 DebuggerStats::ReportStatistics(GetDebugger(), target, stats_options));163 result.SetStatus(eReturnStatusSuccessFinishResult);164 }165 166 CommandOptions m_options;167};168 169CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)170 : CommandObjectMultiword(interpreter, "statistics",171 "Print statistics about a debugging session",172 "statistics <subcommand> [<subcommand-options>]") {173 LoadSubCommand("enable",174 CommandObjectSP(new CommandObjectStatsEnable(interpreter)));175 LoadSubCommand("disable",176 CommandObjectSP(new CommandObjectStatsDisable(interpreter)));177 LoadSubCommand("dump",178 CommandObjectSP(new CommandObjectStatsDump(interpreter)));179}180 181CommandObjectStats::~CommandObjectStats() = default;182