xref: /llvm-project/lldb/source/Commands/CommandObjectDiagnostics.cpp (revision 0d01300aacf6029b6d63f7dcede3ca8e15229d34)
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