xref: /openbsd-src/gnu/llvm/lldb/source/Commands/CommandObjectDiagnostics.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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