summaryrefslogtreecommitdiffstats
path: root/lldb/source/Commands/CommandObjectReproducer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Commands/CommandObjectReproducer.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectReproducer.cpp206
1 files changed, 206 insertions, 0 deletions
diff --git a/lldb/source/Commands/CommandObjectReproducer.cpp b/lldb/source/Commands/CommandObjectReproducer.cpp
new file mode 100644
index 00000000000..e69a6308892
--- /dev/null
+++ b/lldb/source/Commands/CommandObjectReproducer.cpp
@@ -0,0 +1,206 @@
+//===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectReproducer.h"
+
+#include "lldb/Utility/Reproducer.h"
+
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupBoolean.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static void AppendErrorToResult(llvm::Error e, CommandReturnObject &result) {
+ std::string error_str = llvm::toString(std::move(e));
+ result.AppendErrorWithFormat("%s", error_str.c_str());
+}
+
+class CommandObjectReproducerCaptureEnable : public CommandObjectParsed {
+public:
+ CommandObjectReproducerCaptureEnable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer capture enable",
+ "Enable gathering information for reproducer",
+ nullptr) {}
+
+ ~CommandObjectReproducerCaptureEnable() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!command.empty()) {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ auto &r = repro::Reproducer::Instance();
+ if (auto e = r.SetGenerateReproducer(true)) {
+ AppendErrorToResult(std::move(e), result);
+ return false;
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectReproducerCaptureDisable : public CommandObjectParsed {
+public:
+ CommandObjectReproducerCaptureDisable(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer capture enable",
+ "Disable gathering information for reproducer",
+ nullptr) {}
+
+ ~CommandObjectReproducerCaptureDisable() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!command.empty()) {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ auto &r = repro::Reproducer::Instance();
+ if (auto e = r.SetGenerateReproducer(false)) {
+ AppendErrorToResult(std::move(e), result);
+ return false;
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectReproducerGenerate : public CommandObjectParsed {
+public:
+ CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer generate",
+ "Generate reproducer on disk.", nullptr) {}
+
+ ~CommandObjectReproducerGenerate() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (!command.empty()) {
+ result.AppendErrorWithFormat("'%s' takes no arguments",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ auto &r = repro::Reproducer::Instance();
+ if (auto generator = r.GetGenerator()) {
+ generator->Keep();
+ } else {
+ result.AppendErrorWithFormat("Unable to get the reproducer generator");
+ return false;
+ }
+
+ result.GetOutputStream()
+ << "Reproducer written to '" << r.GetReproducerPath() << "'\n";
+
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectReproducerReplay : public CommandObjectParsed {
+public:
+ CommandObjectReproducerReplay(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "reproducer capture",
+ "Enable or disable gathering of information needed "
+ "to generate a reproducer.",
+ nullptr) {
+ CommandArgumentEntry arg1;
+ CommandArgumentData path_arg;
+
+ // Define the first (and only) variant of this arg.
+ path_arg.arg_type = eArgTypePath;
+ path_arg.arg_repetition = eArgRepeatPlain;
+
+ // There is only one variant this argument could be; put it into the
+ // argument entry.
+ arg1.push_back(path_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back(arg1);
+ }
+
+ ~CommandObjectReproducerReplay() override = default;
+
+protected:
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ if (command.empty()) {
+ result.AppendErrorWithFormat(
+ "'%s' takes a single argument: the reproducer path",
+ m_cmd_name.c_str());
+ return false;
+ }
+
+ auto &r = repro::Reproducer::Instance();
+
+ if (auto e = r.SetReplayReproducer(true)) {
+ std::string error_str = llvm::toString(std::move(e));
+ result.AppendErrorWithFormat("%s", error_str.c_str());
+ return false;
+ }
+
+ if (auto loader = r.GetLoader()) {
+ const char *repro_path = command.GetArgumentAtIndex(0);
+ if (auto e = loader->LoadIndex(FileSpec(repro_path))) {
+ std::string error_str = llvm::toString(std::move(e));
+ result.AppendErrorWithFormat("Unable to load reproducer: %s",
+ error_str.c_str());
+ return false;
+ }
+ } else {
+ result.AppendErrorWithFormat("Unable to get the reproducer loader");
+ return false;
+ }
+
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectReproducerCapture : public CommandObjectMultiword {
+private:
+public:
+ CommandObjectReproducerCapture(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(
+ interpreter, "reproducer capture",
+ "Manage gathering of information needed to generate a reproducer.",
+ NULL) {
+ LoadSubCommand(
+ "enable",
+ CommandObjectSP(new CommandObjectReproducerCaptureEnable(interpreter)));
+ LoadSubCommand("disable",
+ CommandObjectSP(
+ new CommandObjectReproducerCaptureDisable(interpreter)));
+ }
+
+ ~CommandObjectReproducerCapture() {}
+};
+
+CommandObjectReproducer::CommandObjectReproducer(
+ CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "reproducer",
+ "Commands controlling LLDB reproducers.",
+ "log <subcommand> [<command-options>]") {
+ LoadSubCommand("capture", CommandObjectSP(new CommandObjectReproducerCapture(
+ interpreter)));
+ LoadSubCommand(
+ "generate",
+ CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
+ LoadSubCommand("replay", CommandObjectSP(
+ new CommandObjectReproducerReplay(interpreter)));
+}
+
+CommandObjectReproducer::~CommandObjectReproducer() = default;
OpenPOWER on IntegriCloud