blob: 4b0e9e36d202bb033dc5dce20a45db5c59b0c99d [file] [log] [blame]
Jonas Devlieghere9e046f02018-11-13 19:18:16 +00001//===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Jonas Devlieghere9e046f02018-11-13 19:18:16 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "CommandObjectReproducer.h"
10
11#include "lldb/Utility/Reproducer.h"
12
Jonas Devliegheredf14b942018-11-15 01:05:40 +000013#include "lldb/Interpreter/CommandInterpreter.h"
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000014#include "lldb/Interpreter/CommandReturnObject.h"
15#include "lldb/Interpreter/OptionArgParser.h"
16#include "lldb/Interpreter/OptionGroupBoolean.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000021class CommandObjectReproducerGenerate : public CommandObjectParsed {
22public:
23 CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
Jonas Devlieghere973d66e2019-05-03 00:10:31 +000024 : CommandObjectParsed(
25 interpreter, "reproducer generate",
26 "Generate reproducer on disk. When the debugger is in capture "
27 "mode, this command will output the reproducer to a directory on "
28 "disk. In replay mode this command in a no-op.",
29 nullptr) {}
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000030
31 ~CommandObjectReproducerGenerate() override = default;
32
33protected:
34 bool DoExecute(Args &command, CommandReturnObject &result) override {
35 if (!command.empty()) {
36 result.AppendErrorWithFormat("'%s' takes no arguments",
37 m_cmd_name.c_str());
38 return false;
39 }
40
41 auto &r = repro::Reproducer::Instance();
42 if (auto generator = r.GetGenerator()) {
43 generator->Keep();
Jonas Devlieghere2dca6532019-02-27 17:47:06 +000044 } else if (r.GetLoader()) {
45 // Make this operation a NOP in replay mode.
46 result.SetStatus(eReturnStatusSuccessFinishNoResult);
47 return result.Succeeded();
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000048 } else {
49 result.AppendErrorWithFormat("Unable to get the reproducer generator");
Jonas Devlieghere2dca6532019-02-27 17:47:06 +000050 result.SetStatus(eReturnStatusFailed);
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000051 return false;
52 }
53
54 result.GetOutputStream()
55 << "Reproducer written to '" << r.GetReproducerPath() << "'\n";
Jonas Devlieghere1c5250a2019-04-02 18:23:16 +000056 result.GetOutputStream()
57 << "Please have a look at the directory to assess if you're willing to "
58 "share the contained information.\n";
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000059
60 result.SetStatus(eReturnStatusSuccessFinishResult);
61 return result.Succeeded();
62 }
63};
64
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000065class CommandObjectReproducerStatus : public CommandObjectParsed {
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000066public:
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000067 CommandObjectReproducerStatus(CommandInterpreter &interpreter)
Jonas Devlieghere973d66e2019-05-03 00:10:31 +000068 : CommandObjectParsed(
69 interpreter, "reproducer status",
70 "Show the current reproducer status. In capture mode the debugger "
71 "is collecting all the information it needs to create a "
72 "reproducer. In replay mode the reproducer is replaying a "
73 "reproducer. When the reproducers are off, no data is collected "
74 "and no reproducer can be generated.",
75 nullptr) {}
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000076
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000077 ~CommandObjectReproducerStatus() override = default;
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000078
79protected:
80 bool DoExecute(Args &command, CommandReturnObject &result) override {
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000081 if (!command.empty()) {
82 result.AppendErrorWithFormat("'%s' takes no arguments",
83 m_cmd_name.c_str());
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000084 return false;
85 }
86
87 auto &r = repro::Reproducer::Instance();
Zachary Turner52f8f342019-01-29 22:55:21 +000088 if (r.GetGenerator()) {
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000089 result.GetOutputStream() << "Reproducer is in capture mode.\n";
Zachary Turner52f8f342019-01-29 22:55:21 +000090 } else if (r.GetLoader()) {
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000091 result.GetOutputStream() << "Reproducer is in replay mode.\n";
92 } else {
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000093 result.GetOutputStream() << "Reproducer is off.\n";
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000094 }
95
Jonas Devlieghere15eacd72018-12-03 17:28:29 +000096 result.SetStatus(eReturnStatusSuccessFinishResult);
Jonas Devlieghere9e046f02018-11-13 19:18:16 +000097 return result.Succeeded();
98 }
99};
100
Jonas Devlieghere9e046f02018-11-13 19:18:16 +0000101CommandObjectReproducer::CommandObjectReproducer(
102 CommandInterpreter &interpreter)
Jonas Devlieghere973d66e2019-05-03 00:10:31 +0000103 : CommandObjectMultiword(
104 interpreter, "reproducer",
105 "Commands to inspect and manipulate the reproducer functionality.",
106 "log <subcommand> [<command-options>]") {
Jonas Devlieghere9e046f02018-11-13 19:18:16 +0000107 LoadSubCommand(
108 "generate",
109 CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
Jonas Devlieghere15eacd72018-12-03 17:28:29 +0000110 LoadSubCommand("status", CommandObjectSP(
111 new CommandObjectReproducerStatus(interpreter)));
Jonas Devlieghere9e046f02018-11-13 19:18:16 +0000112}
113
114CommandObjectReproducer::~CommandObjectReproducer() = default;