xref: /freebsd-src/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- CommandObjectStats.cpp --------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "CommandObjectStats.h"
10349cc55cSDimitry Andric #include "lldb/Core/Debugger.h"
11349cc55cSDimitry Andric #include "lldb/Host/OptionParser.h"
12fcaf7f86SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
130b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
14*0fca6ea1SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
150b57cec5SDimitry Andric #include "lldb/Target/Target.h"
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric using namespace lldb;
180b57cec5SDimitry Andric using namespace lldb_private;
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric class CommandObjectStatsEnable : public CommandObjectParsed {
210b57cec5SDimitry Andric public:
220b57cec5SDimitry Andric   CommandObjectStatsEnable(CommandInterpreter &interpreter)
230b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "enable",
240b57cec5SDimitry Andric                             "Enable statistics collection", nullptr,
250b57cec5SDimitry Andric                             eCommandProcessMustBePaused) {}
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric   ~CommandObjectStatsEnable() override = default;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric protected:
305f757f3fSDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
31349cc55cSDimitry Andric     if (DebuggerStats::GetCollectingStats()) {
320b57cec5SDimitry Andric       result.AppendError("statistics already enabled");
335f757f3fSDimitry Andric       return;
340b57cec5SDimitry Andric     }
350b57cec5SDimitry Andric 
36349cc55cSDimitry Andric     DebuggerStats::SetCollectingStats(true);
370b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
380b57cec5SDimitry Andric   }
390b57cec5SDimitry Andric };
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric class CommandObjectStatsDisable : public CommandObjectParsed {
420b57cec5SDimitry Andric public:
430b57cec5SDimitry Andric   CommandObjectStatsDisable(CommandInterpreter &interpreter)
440b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "disable",
450b57cec5SDimitry Andric                             "Disable statistics collection", nullptr,
460b57cec5SDimitry Andric                             eCommandProcessMustBePaused) {}
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   ~CommandObjectStatsDisable() override = default;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric protected:
515f757f3fSDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
52349cc55cSDimitry Andric     if (!DebuggerStats::GetCollectingStats()) {
530b57cec5SDimitry Andric       result.AppendError("need to enable statistics before disabling them");
545f757f3fSDimitry Andric       return;
550b57cec5SDimitry Andric     }
560b57cec5SDimitry Andric 
57349cc55cSDimitry Andric     DebuggerStats::SetCollectingStats(false);
580b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
590b57cec5SDimitry Andric   }
600b57cec5SDimitry Andric };
610b57cec5SDimitry Andric 
62349cc55cSDimitry Andric #define LLDB_OPTIONS_statistics_dump
63349cc55cSDimitry Andric #include "CommandOptions.inc"
64349cc55cSDimitry Andric 
650b57cec5SDimitry Andric class CommandObjectStatsDump : public CommandObjectParsed {
66349cc55cSDimitry Andric   class CommandOptions : public Options {
67349cc55cSDimitry Andric   public:
6804eeddc0SDimitry Andric     CommandOptions() { OptionParsingStarting(nullptr); }
69349cc55cSDimitry Andric 
70349cc55cSDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
71349cc55cSDimitry Andric                           ExecutionContext *execution_context) override {
72349cc55cSDimitry Andric       Status error;
73349cc55cSDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
74349cc55cSDimitry Andric 
75349cc55cSDimitry Andric       switch (short_option) {
76349cc55cSDimitry Andric       case 'a':
77349cc55cSDimitry Andric         m_all_targets = true;
78349cc55cSDimitry Andric         break;
79*0fca6ea1SDimitry Andric       case 's':
80*0fca6ea1SDimitry Andric         m_stats_options.SetSummaryOnly(true);
81*0fca6ea1SDimitry Andric         break;
82*0fca6ea1SDimitry Andric       case 'f':
83*0fca6ea1SDimitry Andric         m_stats_options.SetLoadAllDebugInfo(true);
84*0fca6ea1SDimitry Andric         break;
85*0fca6ea1SDimitry Andric       case 'r':
86*0fca6ea1SDimitry Andric         if (llvm::Expected<bool> bool_or_error =
87*0fca6ea1SDimitry Andric                 OptionArgParser::ToBoolean("--targets", option_arg))
88*0fca6ea1SDimitry Andric           m_stats_options.SetIncludeTargets(*bool_or_error);
89*0fca6ea1SDimitry Andric         else
90*0fca6ea1SDimitry Andric           error = bool_or_error.takeError();
91*0fca6ea1SDimitry Andric         break;
92*0fca6ea1SDimitry Andric       case 'm':
93*0fca6ea1SDimitry Andric         if (llvm::Expected<bool> bool_or_error =
94*0fca6ea1SDimitry Andric                 OptionArgParser::ToBoolean("--modules", option_arg))
95*0fca6ea1SDimitry Andric           m_stats_options.SetIncludeModules(*bool_or_error);
96*0fca6ea1SDimitry Andric         else
97*0fca6ea1SDimitry Andric           error = bool_or_error.takeError();
98*0fca6ea1SDimitry Andric         break;
99*0fca6ea1SDimitry Andric       case 't':
100*0fca6ea1SDimitry Andric         if (llvm::Expected<bool> bool_or_error =
101*0fca6ea1SDimitry Andric                 OptionArgParser::ToBoolean("--transcript", option_arg))
102*0fca6ea1SDimitry Andric           m_stats_options.SetIncludeTranscript(*bool_or_error);
103*0fca6ea1SDimitry Andric         else
104*0fca6ea1SDimitry Andric           error = bool_or_error.takeError();
105*0fca6ea1SDimitry Andric         break;
106349cc55cSDimitry Andric       default:
107349cc55cSDimitry Andric         llvm_unreachable("Unimplemented option");
108349cc55cSDimitry Andric       }
109349cc55cSDimitry Andric       return error;
110349cc55cSDimitry Andric     }
111349cc55cSDimitry Andric 
112349cc55cSDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
113349cc55cSDimitry Andric       m_all_targets = false;
114*0fca6ea1SDimitry Andric       m_stats_options = StatisticsOptions();
115349cc55cSDimitry Andric     }
116349cc55cSDimitry Andric 
117349cc55cSDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
118bdd1243dSDimitry Andric       return llvm::ArrayRef(g_statistics_dump_options);
119349cc55cSDimitry Andric     }
120349cc55cSDimitry Andric 
121*0fca6ea1SDimitry Andric     const StatisticsOptions &GetStatisticsOptions() { return m_stats_options; }
122*0fca6ea1SDimitry Andric 
123349cc55cSDimitry Andric     bool m_all_targets = false;
124*0fca6ea1SDimitry Andric     StatisticsOptions m_stats_options = StatisticsOptions();
125349cc55cSDimitry Andric   };
126349cc55cSDimitry Andric 
1270b57cec5SDimitry Andric public:
1280b57cec5SDimitry Andric   CommandObjectStatsDump(CommandInterpreter &interpreter)
129349cc55cSDimitry Andric       : CommandObjectParsed(
130349cc55cSDimitry Andric             interpreter, "statistics dump", "Dump metrics in JSON format",
131349cc55cSDimitry Andric             "statistics dump [<options>]", eCommandRequiresTarget) {}
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   ~CommandObjectStatsDump() override = default;
1340b57cec5SDimitry Andric 
135349cc55cSDimitry Andric   Options *GetOptions() override { return &m_options; }
136349cc55cSDimitry Andric 
1370b57cec5SDimitry Andric protected:
1385f757f3fSDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
139349cc55cSDimitry Andric     Target *target = nullptr;
140349cc55cSDimitry Andric     if (!m_options.m_all_targets)
141349cc55cSDimitry Andric       target = m_exe_ctx.GetTargetPtr();
1420b57cec5SDimitry Andric 
143349cc55cSDimitry Andric     result.AppendMessageWithFormatv(
144*0fca6ea1SDimitry Andric         "{0:2}", DebuggerStats::ReportStatistics(
145*0fca6ea1SDimitry Andric                      GetDebugger(), target, m_options.GetStatisticsOptions()));
1460b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
1470b57cec5SDimitry Andric   }
148349cc55cSDimitry Andric 
149349cc55cSDimitry Andric   CommandOptions m_options;
1500b57cec5SDimitry Andric };
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
1530b57cec5SDimitry Andric     : CommandObjectMultiword(interpreter, "statistics",
1540b57cec5SDimitry Andric                              "Print statistics about a debugging session",
1550b57cec5SDimitry Andric                              "statistics <subcommand> [<subcommand-options>]") {
1560b57cec5SDimitry Andric   LoadSubCommand("enable",
1570b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
1580b57cec5SDimitry Andric   LoadSubCommand("disable",
1590b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
1600b57cec5SDimitry Andric   LoadSubCommand("dump",
1610b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectStatsDump(interpreter)));
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric CommandObjectStats::~CommandObjectStats() = default;
165