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