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(); 402dca6538SJonas Devlieghere } else if (r.GetLoader()) { 412dca6538SJonas Devlieghere // Make this operation a NOP in replay mode. 422dca6538SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishNoResult); 432dca6538SJonas Devlieghere return result.Succeeded(); 449e046f02SJonas Devlieghere } else { 459e046f02SJonas Devlieghere result.AppendErrorWithFormat("Unable to get the reproducer generator"); 462dca6538SJonas Devlieghere result.SetStatus(eReturnStatusFailed); 479e046f02SJonas Devlieghere return false; 489e046f02SJonas Devlieghere } 499e046f02SJonas Devlieghere 509e046f02SJonas Devlieghere result.GetOutputStream() 519e046f02SJonas Devlieghere << "Reproducer written to '" << r.GetReproducerPath() << "'\n"; 52*1c5250abSJonas Devlieghere result.GetOutputStream() 53*1c5250abSJonas Devlieghere << "Please have a look at the directory to assess if you're willing to " 54*1c5250abSJonas Devlieghere "share the contained information.\n"; 559e046f02SJonas Devlieghere 569e046f02SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 579e046f02SJonas Devlieghere return result.Succeeded(); 589e046f02SJonas Devlieghere } 599e046f02SJonas Devlieghere }; 609e046f02SJonas Devlieghere 6115eacd74SJonas Devlieghere class CommandObjectReproducerStatus : public CommandObjectParsed { 629e046f02SJonas Devlieghere public: 6315eacd74SJonas Devlieghere CommandObjectReproducerStatus(CommandInterpreter &interpreter) 6415eacd74SJonas Devlieghere : CommandObjectParsed(interpreter, "reproducer status", 6515eacd74SJonas Devlieghere "Show the current reproducer status.", nullptr) {} 669e046f02SJonas Devlieghere 6715eacd74SJonas Devlieghere ~CommandObjectReproducerStatus() override = default; 689e046f02SJonas Devlieghere 699e046f02SJonas Devlieghere protected: 709e046f02SJonas Devlieghere bool DoExecute(Args &command, CommandReturnObject &result) override { 7115eacd74SJonas Devlieghere if (!command.empty()) { 7215eacd74SJonas Devlieghere result.AppendErrorWithFormat("'%s' takes no arguments", 739e046f02SJonas Devlieghere m_cmd_name.c_str()); 749e046f02SJonas Devlieghere return false; 759e046f02SJonas Devlieghere } 769e046f02SJonas Devlieghere 779e046f02SJonas Devlieghere auto &r = repro::Reproducer::Instance(); 7852f8f343SZachary Turner if (r.GetGenerator()) { 7915eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is in capture mode.\n"; 8052f8f343SZachary Turner } else if (r.GetLoader()) { 8115eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is in replay mode.\n"; 8215eacd74SJonas Devlieghere } else { 8315eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is off.\n"; 849e046f02SJonas Devlieghere } 859e046f02SJonas Devlieghere 8615eacd74SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 879e046f02SJonas Devlieghere return result.Succeeded(); 889e046f02SJonas Devlieghere } 899e046f02SJonas Devlieghere }; 909e046f02SJonas Devlieghere 919e046f02SJonas Devlieghere CommandObjectReproducer::CommandObjectReproducer( 929e046f02SJonas Devlieghere CommandInterpreter &interpreter) 939e046f02SJonas Devlieghere : CommandObjectMultiword(interpreter, "reproducer", 949e046f02SJonas Devlieghere "Commands controlling LLDB reproducers.", 959e046f02SJonas Devlieghere "log <subcommand> [<command-options>]") { 969e046f02SJonas Devlieghere LoadSubCommand( 979e046f02SJonas Devlieghere "generate", 989e046f02SJonas Devlieghere CommandObjectSP(new CommandObjectReproducerGenerate(interpreter))); 9915eacd74SJonas Devlieghere LoadSubCommand("status", CommandObjectSP( 10015eacd74SJonas Devlieghere new CommandObjectReproducerStatus(interpreter))); 1019e046f02SJonas Devlieghere } 1029e046f02SJonas Devlieghere 1039e046f02SJonas Devlieghere CommandObjectReproducer::~CommandObjectReproducer() = default; 104