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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "CommandObjectStats.h" 10 #include "lldb/Core/Debugger.h" 11 #include "lldb/Host/OptionParser.h" 12 #include "lldb/Interpreter/CommandOptionArgumentTable.h" 13 #include "lldb/Interpreter/CommandReturnObject.h" 14 #include "lldb/Interpreter/OptionArgParser.h" 15 #include "lldb/Target/Target.h" 16 17 using namespace lldb; 18 using namespace lldb_private; 19 20 class CommandObjectStatsEnable : public CommandObjectParsed { 21 public: 22 CommandObjectStatsEnable(CommandInterpreter &interpreter) 23 : CommandObjectParsed(interpreter, "enable", 24 "Enable statistics collection", nullptr, 25 eCommandProcessMustBePaused) {} 26 27 ~CommandObjectStatsEnable() override = default; 28 29 protected: 30 void DoExecute(Args &command, CommandReturnObject &result) override { 31 if (DebuggerStats::GetCollectingStats()) { 32 result.AppendError("statistics already enabled"); 33 return; 34 } 35 36 DebuggerStats::SetCollectingStats(true); 37 result.SetStatus(eReturnStatusSuccessFinishResult); 38 } 39 }; 40 41 class CommandObjectStatsDisable : public CommandObjectParsed { 42 public: 43 CommandObjectStatsDisable(CommandInterpreter &interpreter) 44 : CommandObjectParsed(interpreter, "disable", 45 "Disable statistics collection", nullptr, 46 eCommandProcessMustBePaused) {} 47 48 ~CommandObjectStatsDisable() override = default; 49 50 protected: 51 void DoExecute(Args &command, CommandReturnObject &result) override { 52 if (!DebuggerStats::GetCollectingStats()) { 53 result.AppendError("need to enable statistics before disabling them"); 54 return; 55 } 56 57 DebuggerStats::SetCollectingStats(false); 58 result.SetStatus(eReturnStatusSuccessFinishResult); 59 } 60 }; 61 62 #define LLDB_OPTIONS_statistics_dump 63 #include "CommandOptions.inc" 64 65 class CommandObjectStatsDump : public CommandObjectParsed { 66 class CommandOptions : public Options { 67 public: 68 CommandOptions() { OptionParsingStarting(nullptr); } 69 70 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 71 ExecutionContext *execution_context) override { 72 Status error; 73 const int short_option = m_getopt_table[option_idx].val; 74 75 switch (short_option) { 76 case 'a': 77 m_all_targets = true; 78 break; 79 case 's': 80 m_stats_options.SetSummaryOnly(true); 81 break; 82 case 'f': 83 m_stats_options.SetLoadAllDebugInfo(true); 84 break; 85 case 'r': 86 if (llvm::Expected<bool> bool_or_error = 87 OptionArgParser::ToBoolean("--targets", option_arg)) 88 m_stats_options.SetIncludeTargets(*bool_or_error); 89 else 90 error = Status::FromError(bool_or_error.takeError()); 91 break; 92 case 'm': 93 if (llvm::Expected<bool> bool_or_error = 94 OptionArgParser::ToBoolean("--modules", option_arg)) 95 m_stats_options.SetIncludeModules(*bool_or_error); 96 else 97 error = Status::FromError(bool_or_error.takeError()); 98 break; 99 case 't': 100 if (llvm::Expected<bool> bool_or_error = 101 OptionArgParser::ToBoolean("--transcript", option_arg)) 102 m_stats_options.SetIncludeTranscript(*bool_or_error); 103 else 104 error = Status::FromError(bool_or_error.takeError()); 105 break; 106 default: 107 llvm_unreachable("Unimplemented option"); 108 } 109 return error; 110 } 111 112 void OptionParsingStarting(ExecutionContext *execution_context) override { 113 m_all_targets = false; 114 m_stats_options = StatisticsOptions(); 115 } 116 117 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 118 return llvm::ArrayRef(g_statistics_dump_options); 119 } 120 121 const StatisticsOptions &GetStatisticsOptions() { return m_stats_options; } 122 123 bool m_all_targets = false; 124 StatisticsOptions m_stats_options = StatisticsOptions(); 125 }; 126 127 public: 128 CommandObjectStatsDump(CommandInterpreter &interpreter) 129 : CommandObjectParsed( 130 interpreter, "statistics dump", "Dump metrics in JSON format", 131 "statistics dump [<options>]", eCommandRequiresTarget) {} 132 133 ~CommandObjectStatsDump() override = default; 134 135 Options *GetOptions() override { return &m_options; } 136 137 protected: 138 void DoExecute(Args &command, CommandReturnObject &result) override { 139 Target *target = nullptr; 140 if (!m_options.m_all_targets) 141 target = m_exe_ctx.GetTargetPtr(); 142 143 result.AppendMessageWithFormatv( 144 "{0:2}", DebuggerStats::ReportStatistics( 145 GetDebugger(), target, m_options.GetStatisticsOptions())); 146 result.SetStatus(eReturnStatusSuccessFinishResult); 147 } 148 149 CommandOptions m_options; 150 }; 151 152 CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter) 153 : CommandObjectMultiword(interpreter, "statistics", 154 "Print statistics about a debugging session", 155 "statistics <subcommand> [<subcommand-options>]") { 156 LoadSubCommand("enable", 157 CommandObjectSP(new CommandObjectStatsEnable(interpreter))); 158 LoadSubCommand("disable", 159 CommandObjectSP(new CommandObjectStatsDisable(interpreter))); 160 LoadSubCommand("dump", 161 CommandObjectSP(new CommandObjectStatsDump(interpreter))); 162 } 163 164 CommandObjectStats::~CommandObjectStats() = default; 165