1 //===-- 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 
14 #include "lldb/Interpreter/CommandInterpreter.h"
15 #include "lldb/Interpreter/CommandReturnObject.h"
16 #include "lldb/Interpreter/OptionArgParser.h"
17 #include "lldb/Interpreter/OptionGroupBoolean.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 class CommandObjectReproducerGenerate : public CommandObjectParsed {
23 public:
24   CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
25       : CommandObjectParsed(interpreter, "reproducer generate",
26                             "Generate reproducer on disk.", nullptr) {}
27 
28   ~CommandObjectReproducerGenerate() override = default;
29 
30 protected:
31   bool DoExecute(Args &command, CommandReturnObject &result) override {
32     if (!command.empty()) {
33       result.AppendErrorWithFormat("'%s' takes no arguments",
34                                    m_cmd_name.c_str());
35       return false;
36     }
37 
38     auto &r = repro::Reproducer::Instance();
39     if (auto generator = r.GetGenerator()) {
40       generator->Keep();
41     } else {
42       result.AppendErrorWithFormat("Unable to get the reproducer generator");
43       return false;
44     }
45 
46     result.GetOutputStream()
47         << "Reproducer written to '" << r.GetReproducerPath() << "'\n";
48 
49     result.SetStatus(eReturnStatusSuccessFinishResult);
50     return result.Succeeded();
51   }
52 };
53 
54 class CommandObjectReproducerStatus : public CommandObjectParsed {
55 public:
56   CommandObjectReproducerStatus(CommandInterpreter &interpreter)
57       : CommandObjectParsed(interpreter, "reproducer status",
58                             "Show the current reproducer status.", nullptr) {}
59 
60   ~CommandObjectReproducerStatus() override = default;
61 
62 protected:
63   bool DoExecute(Args &command, CommandReturnObject &result) override {
64     if (!command.empty()) {
65       result.AppendErrorWithFormat("'%s' takes no arguments",
66                                    m_cmd_name.c_str());
67       return false;
68     }
69 
70     auto &r = repro::Reproducer::Instance();
71     if (auto generator = r.GetGenerator()) {
72       result.GetOutputStream() << "Reproducer is in capture mode.\n";
73     } else if (auto generator = r.GetLoader()) {
74       result.GetOutputStream() << "Reproducer is in replay mode.\n";
75     } else {
76 
77       result.GetOutputStream() << "Reproducer is off.\n";
78     }
79 
80     result.SetStatus(eReturnStatusSuccessFinishResult);
81     return result.Succeeded();
82   }
83 };
84 
85 CommandObjectReproducer::CommandObjectReproducer(
86     CommandInterpreter &interpreter)
87     : CommandObjectMultiword(interpreter, "reproducer",
88                              "Commands controlling LLDB reproducers.",
89                              "log <subcommand> [<command-options>]") {
90   LoadSubCommand(
91       "generate",
92       CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
93   LoadSubCommand("status", CommandObjectSP(
94                                new CommandObjectReproducerStatus(interpreter)));
95 }
96 
97 CommandObjectReproducer::~CommandObjectReproducer() = default;
98