1*0d01300aSJonas Devlieghere //===-- CommandObjectDiagnostics.cpp --------------------------------------===// 2*0d01300aSJonas Devlieghere // 3*0d01300aSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0d01300aSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 5*0d01300aSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0d01300aSJonas Devlieghere // 7*0d01300aSJonas Devlieghere //===----------------------------------------------------------------------===// 8*0d01300aSJonas Devlieghere 9*0d01300aSJonas Devlieghere #include "CommandObjectDiagnostics.h" 10*0d01300aSJonas Devlieghere #include "lldb/Host/OptionParser.h" 11*0d01300aSJonas Devlieghere #include "lldb/Interpreter/CommandOptionArgumentTable.h" 12*0d01300aSJonas Devlieghere #include "lldb/Interpreter/CommandReturnObject.h" 13*0d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionArgParser.h" 14*0d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionValueEnumeration.h" 15*0d01300aSJonas Devlieghere #include "lldb/Interpreter/OptionValueUInt64.h" 16*0d01300aSJonas Devlieghere #include "lldb/Interpreter/Options.h" 17*0d01300aSJonas Devlieghere #include "lldb/Utility/Diagnostics.h" 18*0d01300aSJonas Devlieghere 19*0d01300aSJonas Devlieghere using namespace lldb; 20*0d01300aSJonas Devlieghere using namespace lldb_private; 21*0d01300aSJonas Devlieghere 22*0d01300aSJonas Devlieghere #define LLDB_OPTIONS_diagnostics_dump 23*0d01300aSJonas Devlieghere #include "CommandOptions.inc" 24*0d01300aSJonas Devlieghere 25*0d01300aSJonas Devlieghere class CommandObjectDiagnosticsDump : public CommandObjectParsed { 26*0d01300aSJonas Devlieghere public: 27*0d01300aSJonas Devlieghere // Constructors and Destructors 28*0d01300aSJonas Devlieghere CommandObjectDiagnosticsDump(CommandInterpreter &interpreter) 29*0d01300aSJonas Devlieghere : CommandObjectParsed(interpreter, "diagnostics dump", 30*0d01300aSJonas Devlieghere "Dump diagnostics to disk", nullptr) {} 31*0d01300aSJonas Devlieghere 32*0d01300aSJonas Devlieghere ~CommandObjectDiagnosticsDump() override = default; 33*0d01300aSJonas Devlieghere 34*0d01300aSJonas Devlieghere class CommandOptions : public Options { 35*0d01300aSJonas Devlieghere public: 36*0d01300aSJonas Devlieghere CommandOptions() = default; 37*0d01300aSJonas Devlieghere 38*0d01300aSJonas Devlieghere ~CommandOptions() override = default; 39*0d01300aSJonas Devlieghere 40*0d01300aSJonas Devlieghere Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 41*0d01300aSJonas Devlieghere ExecutionContext *execution_context) override { 42*0d01300aSJonas Devlieghere Status error; 43*0d01300aSJonas Devlieghere const int short_option = m_getopt_table[option_idx].val; 44*0d01300aSJonas Devlieghere 45*0d01300aSJonas Devlieghere switch (short_option) { 46*0d01300aSJonas Devlieghere case 'd': 47*0d01300aSJonas Devlieghere directory.SetDirectory(option_arg); 48*0d01300aSJonas Devlieghere break; 49*0d01300aSJonas Devlieghere default: 50*0d01300aSJonas Devlieghere llvm_unreachable("Unimplemented option"); 51*0d01300aSJonas Devlieghere } 52*0d01300aSJonas Devlieghere return error; 53*0d01300aSJonas Devlieghere } 54*0d01300aSJonas Devlieghere 55*0d01300aSJonas Devlieghere void OptionParsingStarting(ExecutionContext *execution_context) override { 56*0d01300aSJonas Devlieghere directory.Clear(); 57*0d01300aSJonas Devlieghere } 58*0d01300aSJonas Devlieghere 59*0d01300aSJonas Devlieghere llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 60*0d01300aSJonas Devlieghere return llvm::makeArrayRef(g_diagnostics_dump_options); 61*0d01300aSJonas Devlieghere } 62*0d01300aSJonas Devlieghere 63*0d01300aSJonas Devlieghere FileSpec directory; 64*0d01300aSJonas Devlieghere }; 65*0d01300aSJonas Devlieghere 66*0d01300aSJonas Devlieghere Options *GetOptions() override { return &m_options; } 67*0d01300aSJonas Devlieghere 68*0d01300aSJonas Devlieghere protected: 69*0d01300aSJonas Devlieghere llvm::Expected<FileSpec> GetDirectory() { 70*0d01300aSJonas Devlieghere if (m_options.directory) { 71*0d01300aSJonas Devlieghere auto ec = 72*0d01300aSJonas Devlieghere llvm::sys::fs::create_directories(m_options.directory.GetPath()); 73*0d01300aSJonas Devlieghere if (ec) 74*0d01300aSJonas Devlieghere return llvm::errorCodeToError(ec); 75*0d01300aSJonas Devlieghere return m_options.directory; 76*0d01300aSJonas Devlieghere } 77*0d01300aSJonas Devlieghere return Diagnostics::CreateUniqueDirectory(); 78*0d01300aSJonas Devlieghere } 79*0d01300aSJonas Devlieghere 80*0d01300aSJonas Devlieghere bool DoExecute(Args &args, CommandReturnObject &result) override { 81*0d01300aSJonas Devlieghere llvm::Expected<FileSpec> directory = GetDirectory(); 82*0d01300aSJonas Devlieghere 83*0d01300aSJonas Devlieghere if (!directory) { 84*0d01300aSJonas Devlieghere result.AppendError(llvm::toString(directory.takeError())); 85*0d01300aSJonas Devlieghere return result.Succeeded(); 86*0d01300aSJonas Devlieghere } 87*0d01300aSJonas Devlieghere 88*0d01300aSJonas Devlieghere llvm::Error error = Diagnostics::Instance().Create(*directory); 89*0d01300aSJonas Devlieghere if (error) { 90*0d01300aSJonas Devlieghere result.AppendErrorWithFormat("failed to write diagnostics to %s", 91*0d01300aSJonas Devlieghere directory->GetPath().c_str()); 92*0d01300aSJonas Devlieghere result.AppendError(llvm::toString(std::move(error))); 93*0d01300aSJonas Devlieghere return result.Succeeded(); 94*0d01300aSJonas Devlieghere } 95*0d01300aSJonas Devlieghere 96*0d01300aSJonas Devlieghere result.GetOutputStream() << "diagnostics written to " << *directory << '\n'; 97*0d01300aSJonas Devlieghere 98*0d01300aSJonas Devlieghere result.SetStatus(eReturnStatusSuccessFinishResult); 99*0d01300aSJonas Devlieghere return result.Succeeded(); 100*0d01300aSJonas Devlieghere } 101*0d01300aSJonas Devlieghere 102*0d01300aSJonas Devlieghere CommandOptions m_options; 103*0d01300aSJonas Devlieghere }; 104*0d01300aSJonas Devlieghere 105*0d01300aSJonas Devlieghere CommandObjectDiagnostics::CommandObjectDiagnostics( 106*0d01300aSJonas Devlieghere CommandInterpreter &interpreter) 107*0d01300aSJonas Devlieghere : CommandObjectMultiword(interpreter, "diagnostics", 108*0d01300aSJonas Devlieghere "Commands controlling LLDB diagnostics.", 109*0d01300aSJonas Devlieghere "diagnostics <subcommand> [<command-options>]") { 110*0d01300aSJonas Devlieghere LoadSubCommand( 111*0d01300aSJonas Devlieghere "dump", CommandObjectSP(new CommandObjectDiagnosticsDump(interpreter))); 112*0d01300aSJonas Devlieghere } 113*0d01300aSJonas Devlieghere 114*0d01300aSJonas Devlieghere CommandObjectDiagnostics::~CommandObjectDiagnostics() = default; 115