19e046f02SJonas Devlieghere //===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===// 29e046f02SJonas Devlieghere // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 69e046f02SJonas Devlieghere // 79e046f02SJonas Devlieghere //===----------------------------------------------------------------------===// 89e046f02SJonas Devlieghere 99e046f02SJonas Devlieghere #include "CommandObjectReproducer.h" 109e046f02SJonas Devlieghere 119e046f02SJonas Devlieghere #include "lldb/Utility/Reproducer.h" 129e046f02SJonas Devlieghere 13df14b942SJonas Devlieghere #include "lldb/Interpreter/CommandInterpreter.h" 149e046f02SJonas Devlieghere #include "lldb/Interpreter/CommandReturnObject.h" 159e046f02SJonas Devlieghere #include "lldb/Interpreter/OptionArgParser.h" 169e046f02SJonas Devlieghere #include "lldb/Interpreter/OptionGroupBoolean.h" 179e046f02SJonas Devlieghere 189e046f02SJonas Devlieghere using namespace lldb; 199e046f02SJonas Devlieghere using namespace lldb_private; 209e046f02SJonas Devlieghere 219e046f02SJonas Devlieghere class CommandObjectReproducerGenerate : public CommandObjectParsed { 229e046f02SJonas Devlieghere public: 239e046f02SJonas Devlieghere CommandObjectReproducerGenerate(CommandInterpreter &interpreter) 249e046f02SJonas Devlieghere : CommandObjectParsed(interpreter, "reproducer generate", 259e046f02SJonas Devlieghere "Generate reproducer on disk.", nullptr) {} 269e046f02SJonas Devlieghere 279e046f02SJonas Devlieghere ~CommandObjectReproducerGenerate() override = default; 289e046f02SJonas Devlieghere 299e046f02SJonas Devlieghere protected: 309e046f02SJonas Devlieghere bool DoExecute(Args &command, CommandReturnObject &result) override { 319e046f02SJonas Devlieghere if (!command.empty()) { 329e046f02SJonas Devlieghere result.AppendErrorWithFormat("'%s' takes no arguments", 339e046f02SJonas Devlieghere m_cmd_name.c_str()); 349e046f02SJonas Devlieghere return false; 359e046f02SJonas Devlieghere } 369e046f02SJonas Devlieghere 379e046f02SJonas Devlieghere auto &r = repro::Reproducer::Instance(); 389e046f02SJonas Devlieghere if (auto generator = r.GetGenerator()) { 399e046f02SJonas Devlieghere generator->Keep(); 40*2dca6538SJonas Devlieghere } else if (r.GetLoader()) { 41*2dca6538SJonas Devlieghere // Make this operation a NOP in replay mode. 42*2dca6538SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishNoResult); 43*2dca6538SJonas Devlieghere return result.Succeeded(); 449e046f02SJonas Devlieghere } else { 459e046f02SJonas Devlieghere result.AppendErrorWithFormat("Unable to get the reproducer generator"); 46*2dca6538SJonas Devlieghere result.SetStatus(eReturnStatusFailed); 479e046f02SJonas Devlieghere return false; 489e046f02SJonas Devlieghere } 499e046f02SJonas Devlieghere 509e046f02SJonas Devlieghere result.GetOutputStream() 519e046f02SJonas Devlieghere << "Reproducer written to '" << r.GetReproducerPath() << "'\n"; 529e046f02SJonas Devlieghere 539e046f02SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 549e046f02SJonas Devlieghere return result.Succeeded(); 559e046f02SJonas Devlieghere } 569e046f02SJonas Devlieghere }; 579e046f02SJonas Devlieghere 5815eacd74SJonas Devlieghere class CommandObjectReproducerStatus : public CommandObjectParsed { 599e046f02SJonas Devlieghere public: 6015eacd74SJonas Devlieghere CommandObjectReproducerStatus(CommandInterpreter &interpreter) 6115eacd74SJonas Devlieghere : CommandObjectParsed(interpreter, "reproducer status", 6215eacd74SJonas Devlieghere "Show the current reproducer status.", nullptr) {} 639e046f02SJonas Devlieghere 6415eacd74SJonas Devlieghere ~CommandObjectReproducerStatus() override = default; 659e046f02SJonas Devlieghere 669e046f02SJonas Devlieghere protected: 679e046f02SJonas Devlieghere bool DoExecute(Args &command, CommandReturnObject &result) override { 6815eacd74SJonas Devlieghere if (!command.empty()) { 6915eacd74SJonas Devlieghere result.AppendErrorWithFormat("'%s' takes no arguments", 709e046f02SJonas Devlieghere m_cmd_name.c_str()); 719e046f02SJonas Devlieghere return false; 729e046f02SJonas Devlieghere } 739e046f02SJonas Devlieghere 749e046f02SJonas Devlieghere auto &r = repro::Reproducer::Instance(); 7552f8f343SZachary Turner if (r.GetGenerator()) { 7615eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is in capture mode.\n"; 7752f8f343SZachary Turner } else if (r.GetLoader()) { 7815eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is in replay mode.\n"; 7915eacd74SJonas Devlieghere } else { 8015eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is off.\n"; 819e046f02SJonas Devlieghere } 829e046f02SJonas Devlieghere 8315eacd74SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 849e046f02SJonas Devlieghere return result.Succeeded(); 859e046f02SJonas Devlieghere } 869e046f02SJonas Devlieghere }; 879e046f02SJonas Devlieghere 889e046f02SJonas Devlieghere CommandObjectReproducer::CommandObjectReproducer( 899e046f02SJonas Devlieghere CommandInterpreter &interpreter) 909e046f02SJonas Devlieghere : CommandObjectMultiword(interpreter, "reproducer", 919e046f02SJonas Devlieghere "Commands controlling LLDB reproducers.", 929e046f02SJonas Devlieghere "log <subcommand> [<command-options>]") { 939e046f02SJonas Devlieghere LoadSubCommand( 949e046f02SJonas Devlieghere "generate", 959e046f02SJonas Devlieghere CommandObjectSP(new CommandObjectReproducerGenerate(interpreter))); 9615eacd74SJonas Devlieghere LoadSubCommand("status", CommandObjectSP( 9715eacd74SJonas Devlieghere new CommandObjectReproducerStatus(interpreter))); 989e046f02SJonas Devlieghere } 999e046f02SJonas Devlieghere 1009e046f02SJonas Devlieghere CommandObjectReproducer::~CommandObjectReproducer() = default; 101