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/Target/Target.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 class CommandObjectStatsEnable : public CommandObjectParsed {
20 public:
21   CommandObjectStatsEnable(CommandInterpreter &interpreter)
22       : CommandObjectParsed(interpreter, "enable",
23                             "Enable statistics collection", nullptr,
24                             eCommandProcessMustBePaused) {}
25 
26   ~CommandObjectStatsEnable() override = default;
27 
28 protected:
29   bool DoExecute(Args &command, CommandReturnObject &result) override {
30     if (DebuggerStats::GetCollectingStats()) {
31       result.AppendError("statistics already enabled");
32       return false;
33     }
34 
35     DebuggerStats::SetCollectingStats(true);
36     result.SetStatus(eReturnStatusSuccessFinishResult);
37     return true;
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   bool DoExecute(Args &command, CommandReturnObject &result) override {
52     if (!DebuggerStats::GetCollectingStats()) {
53       result.AppendError("need to enable statistics before disabling them");
54       return false;
55     }
56 
57     DebuggerStats::SetCollectingStats(false);
58     result.SetStatus(eReturnStatusSuccessFinishResult);
59     return true;
60   }
61 };
62 
63 #define LLDB_OPTIONS_statistics_dump
64 #include "CommandOptions.inc"
65 
66 class 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       default:
81         llvm_unreachable("Unimplemented option");
82       }
83       return error;
84     }
85 
86     void OptionParsingStarting(ExecutionContext *execution_context) override {
87       m_all_targets = false;
88     }
89 
90     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
91       return llvm::makeArrayRef(g_statistics_dump_options);
92     }
93 
94     bool m_all_targets = false;
95   };
96 
97 public:
98   CommandObjectStatsDump(CommandInterpreter &interpreter)
99       : CommandObjectParsed(
100             interpreter, "statistics dump", "Dump metrics in JSON format",
101             "statistics dump [<options>]", eCommandRequiresTarget) {}
102 
103   ~CommandObjectStatsDump() override = default;
104 
105   Options *GetOptions() override { return &m_options; }
106 
107 protected:
108   bool DoExecute(Args &command, CommandReturnObject &result) override {
109     Target *target = nullptr;
110     if (!m_options.m_all_targets)
111       target = m_exe_ctx.GetTargetPtr();
112 
113     result.AppendMessageWithFormatv(
114         "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target));
115     result.SetStatus(eReturnStatusSuccessFinishResult);
116     return true;
117   }
118 
119   CommandOptions m_options;
120 };
121 
122 CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
123     : CommandObjectMultiword(interpreter, "statistics",
124                              "Print statistics about a debugging session",
125                              "statistics <subcommand> [<subcommand-options>]") {
126   LoadSubCommand("enable",
127                  CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
128   LoadSubCommand("disable",
129                  CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
130   LoadSubCommand("dump",
131                  CommandObjectSP(new CommandObjectStatsDump(interpreter)));
132 }
133 
134 CommandObjectStats::~CommandObjectStats() = default;
135