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