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