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:
CommandObjectStatsEnable(CommandInterpreter & interpreter)22 CommandObjectStatsEnable(CommandInterpreter &interpreter)
23 : CommandObjectParsed(interpreter, "enable",
24 "Enable statistics collection", nullptr,
25 eCommandProcessMustBePaused) {}
26
27 ~CommandObjectStatsEnable() override = default;
28
29 protected:
DoExecute(Args & command,CommandReturnObject & result)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:
CommandObjectStatsDisable(CommandInterpreter & interpreter)43 CommandObjectStatsDisable(CommandInterpreter &interpreter)
44 : CommandObjectParsed(interpreter, "disable",
45 "Disable statistics collection", nullptr,
46 eCommandProcessMustBePaused) {}
47
48 ~CommandObjectStatsDisable() override = default;
49
50 protected:
DoExecute(Args & command,CommandReturnObject & result)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:
CommandOptions()68 CommandOptions() { OptionParsingStarting(nullptr); }
69
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)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 = 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 = 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 = bool_or_error.takeError();
105 break;
106 default:
107 llvm_unreachable("Unimplemented option");
108 }
109 return error;
110 }
111
OptionParsingStarting(ExecutionContext * execution_context)112 void OptionParsingStarting(ExecutionContext *execution_context) override {
113 m_all_targets = false;
114 m_stats_options = StatisticsOptions();
115 }
116
GetDefinitions()117 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
118 return llvm::ArrayRef(g_statistics_dump_options);
119 }
120
GetStatisticsOptions()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:
CommandObjectStatsDump(CommandInterpreter & interpreter)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
GetOptions()135 Options *GetOptions() override { return &m_options; }
136
137 protected:
DoExecute(Args & command,CommandReturnObject & result)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
CommandObjectStats(CommandInterpreter & interpreter)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