10d01300aSJonas Devlieghere //===-- CommandObjectDiagnostics.cpp --------------------------------------===// 20d01300aSJonas Devlieghere // 30d01300aSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40d01300aSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 50d01300aSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60d01300aSJonas Devlieghere // 70d01300aSJonas Devlieghere //===----------------------------------------------------------------------===// 80d01300aSJonas Devlieghere 90d01300aSJonas Devlieghere #include "CommandObjectDiagnostics.h" 100d01300aSJonas Devlieghere #include "lldb/Host/OptionParser.h" 110d01300aSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h" 120d01300aSJonas Devlieghere #include "lldb/Interpreter/CommandReturnObject.h" 130d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionArgParser.h" 140d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionValueEnumeration.h" 150d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionValueUInt64.h" 160d01300aSJonas Devlieghere #include "lldb/Interpreter/Options.h" 170d01300aSJonas Devlieghere #include "lldb/Utility/Diagnostics.h" 180d01300aSJonas Devlieghere 190d01300aSJonas Devlieghere using namespace lldb; 200d01300aSJonas Devlieghere using namespace lldb_private; 210d01300aSJonas Devlieghere 220d01300aSJonas Devlieghere #define LLDB_OPTIONS_diagnostics_dump 230d01300aSJonas Devlieghere #include "CommandOptions.inc" 240d01300aSJonas Devlieghere 250d01300aSJonas Devlieghere class CommandObjectDiagnosticsDump : public CommandObjectParsed { 260d01300aSJonas Devlieghere public: 270d01300aSJonas Devlieghere // Constructors and Destructors 280d01300aSJonas Devlieghere CommandObjectDiagnosticsDump(CommandInterpreter &interpreter) 290d01300aSJonas Devlieghere : CommandObjectParsed(interpreter, "diagnostics dump", 300d01300aSJonas Devlieghere "Dump diagnostics to disk", nullptr) {} 310d01300aSJonas Devlieghere 320d01300aSJonas Devlieghere ~CommandObjectDiagnosticsDump() override = default; 330d01300aSJonas Devlieghere 340d01300aSJonas Devlieghere class CommandOptions : public Options { 350d01300aSJonas Devlieghere public: 360d01300aSJonas Devlieghere CommandOptions() = default; 370d01300aSJonas Devlieghere 380d01300aSJonas Devlieghere ~CommandOptions() override = default; 390d01300aSJonas Devlieghere 400d01300aSJonas Devlieghere Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 410d01300aSJonas Devlieghere ExecutionContext *execution_context) override { 420d01300aSJonas Devlieghere Status error; 430d01300aSJonas Devlieghere const int short_option = m_getopt_table[option_idx].val; 440d01300aSJonas Devlieghere 450d01300aSJonas Devlieghere switch (short_option) { 460d01300aSJonas Devlieghere case 'd': 470d01300aSJonas Devlieghere directory.SetDirectory(option_arg); 480d01300aSJonas Devlieghere break; 490d01300aSJonas Devlieghere default: 500d01300aSJonas Devlieghere llvm_unreachable("Unimplemented option"); 510d01300aSJonas Devlieghere } 520d01300aSJonas Devlieghere return error; 530d01300aSJonas Devlieghere } 540d01300aSJonas Devlieghere 550d01300aSJonas Devlieghere void OptionParsingStarting(ExecutionContext *execution_context) override { 560d01300aSJonas Devlieghere directory.Clear(); 570d01300aSJonas Devlieghere } 580d01300aSJonas Devlieghere 590d01300aSJonas Devlieghere llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 60*984b800aSserge-sans-paille return llvm::ArrayRef(g_diagnostics_dump_options); 610d01300aSJonas Devlieghere } 620d01300aSJonas Devlieghere 630d01300aSJonas Devlieghere FileSpec directory; 640d01300aSJonas Devlieghere }; 650d01300aSJonas Devlieghere 660d01300aSJonas Devlieghere Options *GetOptions() override { return &m_options; } 670d01300aSJonas Devlieghere 680d01300aSJonas Devlieghere protected: 690d01300aSJonas Devlieghere llvm::Expected<FileSpec> GetDirectory() { 700d01300aSJonas Devlieghere if (m_options.directory) { 710d01300aSJonas Devlieghere auto ec = 720d01300aSJonas Devlieghere llvm::sys::fs::create_directories(m_options.directory.GetPath()); 730d01300aSJonas Devlieghere if (ec) 740d01300aSJonas Devlieghere return llvm::errorCodeToError(ec); 750d01300aSJonas Devlieghere return m_options.directory; 760d01300aSJonas Devlieghere } 770d01300aSJonas Devlieghere return Diagnostics::CreateUniqueDirectory(); 780d01300aSJonas Devlieghere } 790d01300aSJonas Devlieghere 800d01300aSJonas Devlieghere bool DoExecute(Args &args, CommandReturnObject &result) override { 810d01300aSJonas Devlieghere llvm::Expected<FileSpec> directory = GetDirectory(); 820d01300aSJonas Devlieghere 830d01300aSJonas Devlieghere if (!directory) { 840d01300aSJonas Devlieghere result.AppendError(llvm::toString(directory.takeError())); 850d01300aSJonas Devlieghere return result.Succeeded(); 860d01300aSJonas Devlieghere } 870d01300aSJonas Devlieghere 880d01300aSJonas Devlieghere llvm::Error error = Diagnostics::Instance().Create(*directory); 890d01300aSJonas Devlieghere if (error) { 900d01300aSJonas Devlieghere result.AppendErrorWithFormat("failed to write diagnostics to %s", 910d01300aSJonas Devlieghere directory->GetPath().c_str()); 920d01300aSJonas Devlieghere result.AppendError(llvm::toString(std::move(error))); 930d01300aSJonas Devlieghere return result.Succeeded(); 940d01300aSJonas Devlieghere } 950d01300aSJonas Devlieghere 960d01300aSJonas Devlieghere result.GetOutputStream() << "diagnostics written to " << *directory << '\n'; 970d01300aSJonas Devlieghere 980d01300aSJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 990d01300aSJonas Devlieghere return result.Succeeded(); 1000d01300aSJonas Devlieghere } 1010d01300aSJonas Devlieghere 1020d01300aSJonas Devlieghere CommandOptions m_options; 1030d01300aSJonas Devlieghere }; 1040d01300aSJonas Devlieghere 1050d01300aSJonas Devlieghere CommandObjectDiagnostics::CommandObjectDiagnostics( 1060d01300aSJonas Devlieghere CommandInterpreter &interpreter) 1070d01300aSJonas Devlieghere : CommandObjectMultiword(interpreter, "diagnostics", 1080d01300aSJonas Devlieghere "Commands controlling LLDB diagnostics.", 1090d01300aSJonas Devlieghere "diagnostics <subcommand> [<command-options>]") { 1100d01300aSJonas Devlieghere LoadSubCommand( 1110d01300aSJonas Devlieghere "dump", CommandObjectSP(new CommandObjectDiagnosticsDump(interpreter))); 1120d01300aSJonas Devlieghere } 1130d01300aSJonas Devlieghere 1140d01300aSJonas Devlieghere CommandObjectDiagnostics::~CommandObjectDiagnostics() = default; 115