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