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) 24973d66eeSJonas Devlieghere : CommandObjectParsed( 25973d66eeSJonas Devlieghere interpreter, "reproducer generate", 26973d66eeSJonas Devlieghere "Generate reproducer on disk. When the debugger is in capture " 27973d66eeSJonas Devlieghere "mode, this command will output the reproducer to a directory on " 28973d66eeSJonas Devlieghere "disk. In replay mode this command in a no-op.", 29973d66eeSJonas Devlieghere nullptr) {} 309e046f02SJonas Devlieghere 319e046f02SJonas Devlieghere ~CommandObjectReproducerGenerate() override = default; 329e046f02SJonas Devlieghere 339e046f02SJonas Devlieghere protected: 349e046f02SJonas Devlieghere bool DoExecute(Args &command, CommandReturnObject &result) override { 359e046f02SJonas Devlieghere if (!command.empty()) { 369e046f02SJonas Devlieghere result.AppendErrorWithFormat("'%s' takes no arguments", 379e046f02SJonas Devlieghere m_cmd_name.c_str()); 389e046f02SJonas Devlieghere return false; 399e046f02SJonas Devlieghere } 409e046f02SJonas Devlieghere 419e046f02SJonas Devlieghere auto &r = repro::Reproducer::Instance(); 429e046f02SJonas Devlieghere if (auto generator = r.GetGenerator()) { 439e046f02SJonas Devlieghere generator->Keep(); 442dca6538SJonas Devlieghere } else if (r.GetLoader()) { 452dca6538SJonas Devlieghere // Make this operation a NOP in replay mode. 462dca6538SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishNoResult); 472dca6538SJonas Devlieghere return result.Succeeded(); 489e046f02SJonas Devlieghere } else { 499e046f02SJonas Devlieghere result.AppendErrorWithFormat("Unable to get the reproducer generator"); 502dca6538SJonas Devlieghere result.SetStatus(eReturnStatusFailed); 519e046f02SJonas Devlieghere return false; 529e046f02SJonas Devlieghere } 539e046f02SJonas Devlieghere 549e046f02SJonas Devlieghere result.GetOutputStream() 559e046f02SJonas Devlieghere << "Reproducer written to '" << r.GetReproducerPath() << "'\n"; 561c5250abSJonas Devlieghere result.GetOutputStream() 571c5250abSJonas Devlieghere << "Please have a look at the directory to assess if you're willing to " 581c5250abSJonas Devlieghere "share the contained information.\n"; 599e046f02SJonas Devlieghere 609e046f02SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 619e046f02SJonas Devlieghere return result.Succeeded(); 629e046f02SJonas Devlieghere } 639e046f02SJonas Devlieghere }; 649e046f02SJonas Devlieghere 6515eacd74SJonas Devlieghere class CommandObjectReproducerStatus : public CommandObjectParsed { 669e046f02SJonas Devlieghere public: 6715eacd74SJonas Devlieghere CommandObjectReproducerStatus(CommandInterpreter &interpreter) 68973d66eeSJonas Devlieghere : CommandObjectParsed( 69973d66eeSJonas Devlieghere interpreter, "reproducer status", 70973d66eeSJonas Devlieghere "Show the current reproducer status. In capture mode the debugger " 71973d66eeSJonas Devlieghere "is collecting all the information it needs to create a " 72973d66eeSJonas Devlieghere "reproducer. In replay mode the reproducer is replaying a " 73973d66eeSJonas Devlieghere "reproducer. When the reproducers are off, no data is collected " 74973d66eeSJonas Devlieghere "and no reproducer can be generated.", 75973d66eeSJonas Devlieghere nullptr) {} 769e046f02SJonas Devlieghere 7715eacd74SJonas Devlieghere ~CommandObjectReproducerStatus() override = default; 789e046f02SJonas Devlieghere 799e046f02SJonas Devlieghere protected: 809e046f02SJonas Devlieghere bool DoExecute(Args &command, CommandReturnObject &result) override { 8115eacd74SJonas Devlieghere if (!command.empty()) { 8215eacd74SJonas Devlieghere result.AppendErrorWithFormat("'%s' takes no arguments", 839e046f02SJonas Devlieghere m_cmd_name.c_str()); 849e046f02SJonas Devlieghere return false; 859e046f02SJonas Devlieghere } 869e046f02SJonas Devlieghere 879e046f02SJonas Devlieghere auto &r = repro::Reproducer::Instance(); 8852f8f343SZachary Turner if (r.GetGenerator()) { 8915eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is in capture mode.\n"; 9052f8f343SZachary Turner } else if (r.GetLoader()) { 9115eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is in replay mode.\n"; 9215eacd74SJonas Devlieghere } else { 9315eacd74SJonas Devlieghere result.GetOutputStream() << "Reproducer is off.\n"; 949e046f02SJonas Devlieghere } 959e046f02SJonas Devlieghere 9615eacd74SJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 979e046f02SJonas Devlieghere return result.Succeeded(); 989e046f02SJonas Devlieghere } 999e046f02SJonas Devlieghere }; 1009e046f02SJonas Devlieghere 1019e046f02SJonas Devlieghere CommandObjectReproducer::CommandObjectReproducer( 1029e046f02SJonas Devlieghere CommandInterpreter &interpreter) 103973d66eeSJonas Devlieghere : CommandObjectMultiword( 104973d66eeSJonas Devlieghere interpreter, "reproducer", 105*130ec068SJonas Devlieghere "Commands for manipulate the reproducer functionality.", 106*130ec068SJonas Devlieghere "reproducer <subcommand> [<subcommand-options>]") { 1079e046f02SJonas Devlieghere LoadSubCommand( 1089e046f02SJonas Devlieghere "generate", 1099e046f02SJonas Devlieghere CommandObjectSP(new CommandObjectReproducerGenerate(interpreter))); 11015eacd74SJonas Devlieghere LoadSubCommand("status", CommandObjectSP( 11115eacd74SJonas Devlieghere new CommandObjectReproducerStatus(interpreter))); 1129e046f02SJonas Devlieghere } 1139e046f02SJonas Devlieghere 1149e046f02SJonas Devlieghere CommandObjectReproducer::~CommandObjectReproducer() = default; 115