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   void DoExecute(Args &command, CommandReturnObject &result) override {
30     if (DebuggerStats::GetCollectingStats()) {
31       result.AppendError("statistics already enabled");
32       return;
33     }
34 
35     DebuggerStats::SetCollectingStats(true);
36     result.SetStatus(eReturnStatusSuccessFinishResult);
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   void DoExecute(Args &command, CommandReturnObject &result) override {
51     if (!DebuggerStats::GetCollectingStats()) {
52       result.AppendError("need to enable statistics before disabling them");
53       return;
54     }
55 
56     DebuggerStats::SetCollectingStats(false);
57     result.SetStatus(eReturnStatusSuccessFinishResult);
58   }
59 };
60 
61 #define LLDB_OPTIONS_statistics_dump
62 #include "CommandOptions.inc"
63 
64 class CommandObjectStatsDump : public CommandObjectParsed {
65   class CommandOptions : public Options {
66   public:
67     CommandOptions() { OptionParsingStarting(nullptr); }
68 
69     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
70                           ExecutionContext *execution_context) override {
71       Status error;
72       const int short_option = m_getopt_table[option_idx].val;
73 
74       switch (short_option) {
75       case 'a':
76         m_all_targets = true;
77         break;
78       default:
79         llvm_unreachable("Unimplemented option");
80       }
81       return error;
82     }
83 
84     void OptionParsingStarting(ExecutionContext *execution_context) override {
85       m_all_targets = false;
86     }
87 
88     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
89       return llvm::ArrayRef(g_statistics_dump_options);
90     }
91 
92     bool m_all_targets = false;
93   };
94 
95 public:
96   CommandObjectStatsDump(CommandInterpreter &interpreter)
97       : CommandObjectParsed(
98             interpreter, "statistics dump", "Dump metrics in JSON format",
99             "statistics dump [<options>]", eCommandRequiresTarget) {}
100 
101   ~CommandObjectStatsDump() override = default;
102 
103   Options *GetOptions() override { return &m_options; }
104 
105 protected:
106   void DoExecute(Args &command, CommandReturnObject &result) override {
107     Target *target = nullptr;
108     if (!m_options.m_all_targets)
109       target = m_exe_ctx.GetTargetPtr();
110 
111     result.AppendMessageWithFormatv(
112         "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target));
113     result.SetStatus(eReturnStatusSuccessFinishResult);
114   }
115 
116   CommandOptions m_options;
117 };
118 
119 CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
120     : CommandObjectMultiword(interpreter, "statistics",
121                              "Print statistics about a debugging session",
122                              "statistics <subcommand> [<subcommand-options>]") {
123   LoadSubCommand("enable",
124                  CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
125   LoadSubCommand("disable",
126                  CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
127   LoadSubCommand("dump",
128                  CommandObjectSP(new CommandObjectStatsDump(interpreter)));
129 }
130 
131 CommandObjectStats::~CommandObjectStats() = default;
132