blob: 03a3e2309802d2c50f03584341615bb9e7cc02bc [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
Jonas Devlieghere68ed93d2018-11-27 22:11:02 +0000146 const char *repro_path = command.GetArgumentAtIndex(0);
147 if (auto e = r.SetReplay(FileSpec(repro_path))) {
Jonas Devlieghere9e046f02018-11-13 19:18:16 +0000148 std::string error_str = llvm::toString(std::move(e));
149 result.AppendErrorWithFormat("%s", error_str.c_str());
150 return false;
151 }
152
Jonas Devlieghere9e046f02018-11-13 19:18:16 +0000153 result.SetStatus(eReturnStatusSuccessFinishNoResult);
154 return result.Succeeded();
155 }
156};
157
158class CommandObjectReproducerCapture : public CommandObjectMultiword {
159private:
160public:
161 CommandObjectReproducerCapture(CommandInterpreter &interpreter)
162 : CommandObjectMultiword(
163 interpreter, "reproducer capture",
164 "Manage gathering of information needed to generate a reproducer.",
165 NULL) {
166 LoadSubCommand(
167 "enable",
168 CommandObjectSP(new CommandObjectReproducerCaptureEnable(interpreter)));
169 LoadSubCommand("disable",
170 CommandObjectSP(
171 new CommandObjectReproducerCaptureDisable(interpreter)));
172 }
173
174 ~CommandObjectReproducerCapture() {}
175};
176
177CommandObjectReproducer::CommandObjectReproducer(
178 CommandInterpreter &interpreter)
179 : CommandObjectMultiword(interpreter, "reproducer",
180 "Commands controlling LLDB reproducers.",
181 "log <subcommand> [<command-options>]") {
182 LoadSubCommand("capture", CommandObjectSP(new CommandObjectReproducerCapture(
183 interpreter)));
184 LoadSubCommand(
185 "generate",
186 CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
187 LoadSubCommand("replay", CommandObjectSP(
188 new CommandObjectReproducerReplay(interpreter)));
189}
190
191CommandObjectReproducer::~CommandObjectReproducer() = default;