blob: a1fdb4a1fcdf2454563e1189b998047a81e41b73 [file] [log] [blame]
Jonas Devlieghere9e046f02018-11-13 19:18:16 +00001//===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectReproducer.h"
11
12#include "lldb/Utility/Reproducer.h"
13
Jonas Devliegheredf14b942018-11-15 01:05:40 +000014#include "lldb/Interpreter/CommandInterpreter.h"
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000015#include "lldb/Interpreter/CommandReturnObject.h"
16#include "lldb/Interpreter/OptionArgParser.h"
17#include "lldb/Interpreter/OptionGroupBoolean.h"
18
19using namespace lldb;
20using namespace lldb_private;
21
22static void AppendErrorToResult(llvm::Error e, CommandReturnObject &result) {
23 std::string error_str = llvm::toString(std::move(e));
24 result.AppendErrorWithFormat("%s", error_str.c_str());
25}
26
27class CommandObjectReproducerCaptureEnable : public CommandObjectParsed {
28public:
29 CommandObjectReproducerCaptureEnable(CommandInterpreter &interpreter)
30 : CommandObjectParsed(interpreter, "reproducer capture enable",
31 "Enable gathering information for reproducer",
32 nullptr) {}
33
34 ~CommandObjectReproducerCaptureEnable() override = default;
35
36protected:
37 bool DoExecute(Args &command, CommandReturnObject &result) override {
38 if (!command.empty()) {
39 result.AppendErrorWithFormat("'%s' takes no arguments",
40 m_cmd_name.c_str());
41 return false;
42 }
43
Jonas Devliegheredf14b942018-11-15 01:05:40 +000044 if (auto e = m_interpreter.GetDebugger().SetReproducerCapture(true)) {
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000045 AppendErrorToResult(std::move(e), result);
46 return false;
47 }
48
49 result.SetStatus(eReturnStatusSuccessFinishNoResult);
50 return result.Succeeded();
51 }
52};
53
54class CommandObjectReproducerCaptureDisable : public CommandObjectParsed {
55public:
56 CommandObjectReproducerCaptureDisable(CommandInterpreter &interpreter)
57 : CommandObjectParsed(interpreter, "reproducer capture enable",
58 "Disable gathering information for reproducer",
59 nullptr) {}
60
61 ~CommandObjectReproducerCaptureDisable() override = default;
62
63protected:
64 bool DoExecute(Args &command, CommandReturnObject &result) override {
65 if (!command.empty()) {
66 result.AppendErrorWithFormat("'%s' takes no arguments",
67 m_cmd_name.c_str());
68 return false;
69 }
70
Jonas Devliegheredf14b942018-11-15 01:05:40 +000071 if (auto e = m_interpreter.GetDebugger().SetReproducerCapture(false)) {
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000072 AppendErrorToResult(std::move(e), result);
73 return false;
74 }
75
76 result.SetStatus(eReturnStatusSuccessFinishNoResult);
77 return result.Succeeded();
78 }
79};
80
81class CommandObjectReproducerGenerate : public CommandObjectParsed {
82public:
83 CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
84 : CommandObjectParsed(interpreter, "reproducer generate",
85 "Generate reproducer on disk.", nullptr) {}
86
87 ~CommandObjectReproducerGenerate() override = default;
88
89protected:
90 bool DoExecute(Args &command, CommandReturnObject &result) override {
91 if (!command.empty()) {
92 result.AppendErrorWithFormat("'%s' takes no arguments",
93 m_cmd_name.c_str());
94 return false;
95 }
96
97 auto &r = repro::Reproducer::Instance();
98 if (auto generator = r.GetGenerator()) {
99 generator->Keep();
100 } else {
101 result.AppendErrorWithFormat("Unable to get the reproducer generator");
102 return false;
103 }
104
105 result.GetOutputStream()
106 << "Reproducer written to '" << r.GetReproducerPath() << "'\n";
107
108 result.SetStatus(eReturnStatusSuccessFinishResult);
109 return result.Succeeded();
110 }
111};
112
113class CommandObjectReproducerReplay : public CommandObjectParsed {
114public:
115 CommandObjectReproducerReplay(CommandInterpreter &interpreter)
Jonas Devliegheredf14b942018-11-15 01:05:40 +0000116 : CommandObjectParsed(interpreter, "reproducer replay",
117 "Replay a reproducer.", nullptr) {
Jonas Devlieghere9e046f02018-11-13 19:18:16 +0000118 CommandArgumentEntry arg1;
119 CommandArgumentData path_arg;
120
121 // Define the first (and only) variant of this arg.
122 path_arg.arg_type = eArgTypePath;
123 path_arg.arg_repetition = eArgRepeatPlain;
124
125 // There is only one variant this argument could be; put it into the
126 // argument entry.
127 arg1.push_back(path_arg);
128
129 // Push the data for the first argument into the m_arguments vector.
130 m_arguments.push_back(arg1);
131 }
132
133 ~CommandObjectReproducerReplay() override = default;
134
135protected:
136 bool DoExecute(Args &command, CommandReturnObject &result) override {
137 if (command.empty()) {
138 result.AppendErrorWithFormat(
139 "'%s' takes a single argument: the reproducer path",
140 m_cmd_name.c_str());
141 return false;
142 }
143
144 auto &r = repro::Reproducer::Instance();
145
146 if (auto e = r.SetReplayReproducer(true)) {
147 std::string error_str = llvm::toString(std::move(e));
148 result.AppendErrorWithFormat("%s", error_str.c_str());
149 return false;
150 }
151
152 if (auto loader = r.GetLoader()) {
153 const char *repro_path = command.GetArgumentAtIndex(0);
154 if (auto e = loader->LoadIndex(FileSpec(repro_path))) {
155 std::string error_str = llvm::toString(std::move(e));
156 result.AppendErrorWithFormat("Unable to load reproducer: %s",
157 error_str.c_str());
158 return false;
159 }
160 } else {
161 result.AppendErrorWithFormat("Unable to get the reproducer loader");
162 return false;
163 }
164
165 result.SetStatus(eReturnStatusSuccessFinishNoResult);
166 return result.Succeeded();
167 }
168};
169
170class CommandObjectReproducerCapture : public CommandObjectMultiword {
171private:
172public:
173 CommandObjectReproducerCapture(CommandInterpreter &interpreter)
174 : CommandObjectMultiword(
175 interpreter, "reproducer capture",
176 "Manage gathering of information needed to generate a reproducer.",
177 NULL) {
178 LoadSubCommand(
179 "enable",
180 CommandObjectSP(new CommandObjectReproducerCaptureEnable(interpreter)));
181 LoadSubCommand("disable",
182 CommandObjectSP(
183 new CommandObjectReproducerCaptureDisable(interpreter)));
184 }
185
186 ~CommandObjectReproducerCapture() {}
187};
188
189CommandObjectReproducer::CommandObjectReproducer(
190 CommandInterpreter &interpreter)
191 : CommandObjectMultiword(interpreter, "reproducer",
192 "Commands controlling LLDB reproducers.",
193 "log <subcommand> [<command-options>]") {
194 LoadSubCommand("capture", CommandObjectSP(new CommandObjectReproducerCapture(
195 interpreter)));
196 LoadSubCommand(
197 "generate",
198 CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
199 LoadSubCommand("replay", CommandObjectSP(
200 new CommandObjectReproducerReplay(interpreter)));
201}
202
203CommandObjectReproducer::~CommandObjectReproducer() = default;