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