This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG0d01300aacf6: [lldb] Add a "diagnostics dump" command (authored by JDevlieghere). Herald added a project: LLDB.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D135622/new/ https://reviews.llvm.org/D135622 Files: lldb/include/lldb/Utility/Diagnostics.h lldb/source/Commands/CMakeLists.txt lldb/source/Commands/CommandObjectDiagnostics.cpp lldb/source/Commands/CommandObjectDiagnostics.h lldb/source/Commands/Options.td lldb/source/Interpreter/CommandInterpreter.cpp lldb/source/Utility/Diagnostics.cpp lldb/test/Shell/Diagnostics/TestDump.test
Index: lldb/test/Shell/Diagnostics/TestDump.test =================================================================== --- /dev/null +++ lldb/test/Shell/Diagnostics/TestDump.test @@ -0,0 +1,15 @@ +# Check that the diagnostics dump command uses the correct directory and +# creates one if needed. + +# Dump to an existing directory. +# RUN: rm -rf %t.existing +# RUN: mkdir -p %t.existing +# RUN: %lldb -o 'diagnostics dump -d %t.existing' +# RUN: file %t.existing | FileCheck %s + +# Dump to a non-existing directory. +# RUN: rm -rf %t.nonexisting +# RUN: %lldb -o 'diagnostics dump -d %t.nonexisting' +# RUN: file %t.nonexisting | FileCheck %s + +# CHECK: : directory Index: lldb/source/Utility/Diagnostics.cpp =================================================================== --- lldb/source/Utility/Diagnostics.cpp +++ lldb/source/Utility/Diagnostics.cpp @@ -44,19 +44,21 @@ } bool Diagnostics::Dump(raw_ostream &stream) { - SmallString<128> diagnostics_dir; - std::error_code ec = - sys::fs::createUniqueDirectory("diagnostics", diagnostics_dir); - if (ec) { + Expected<FileSpec> diagnostics_dir = CreateUniqueDirectory(); + if (!diagnostics_dir) { stream << "unable to create diagnostic dir: " - << toString(errorCodeToError(ec)) << '\n'; + << toString(diagnostics_dir.takeError()) << '\n'; return false; } - stream << "LLDB diagnostics written to " << diagnostics_dir << "\n"; + return Dump(stream, *diagnostics_dir); +} + +bool Diagnostics::Dump(raw_ostream &stream, const FileSpec &dir) { + stream << "LLDB diagnostics will be written to " << dir.GetPath() << "\n"; stream << "Please include the directory content when filing a bug report\n"; - Error error = Create(FileSpec(diagnostics_dir.str())); + Error error = Create(dir); if (error) { stream << toString(std::move(error)) << '\n'; return false; @@ -65,6 +67,15 @@ return true; } +llvm::Expected<FileSpec> Diagnostics::CreateUniqueDirectory() { + SmallString<128> diagnostics_dir; + std::error_code ec = + sys::fs::createUniqueDirectory("diagnostics", diagnostics_dir); + if (ec) + return errorCodeToError(ec); + return FileSpec(diagnostics_dir.str()); +} + Error Diagnostics::Create(const FileSpec &dir) { for (Callback c : m_callbacks) { if (Error err = c(dir)) Index: lldb/source/Interpreter/CommandInterpreter.cpp =================================================================== --- lldb/source/Interpreter/CommandInterpreter.cpp +++ lldb/source/Interpreter/CommandInterpreter.cpp @@ -15,6 +15,7 @@ #include "Commands/CommandObjectApropos.h" #include "Commands/CommandObjectBreakpoint.h" #include "Commands/CommandObjectCommands.h" +#include "Commands/CommandObjectDiagnostics.h" #include "Commands/CommandObjectDisassemble.h" #include "Commands/CommandObjectExpression.h" #include "Commands/CommandObjectFrame.h" @@ -518,6 +519,7 @@ REGISTER_COMMAND_OBJECT("apropos", CommandObjectApropos); REGISTER_COMMAND_OBJECT("breakpoint", CommandObjectMultiwordBreakpoint); REGISTER_COMMAND_OBJECT("command", CommandObjectMultiwordCommands); + REGISTER_COMMAND_OBJECT("diagnostics", CommandObjectDiagnostics); REGISTER_COMMAND_OBJECT("disassemble", CommandObjectDisassemble); REGISTER_COMMAND_OBJECT("expression", CommandObjectExpression); REGISTER_COMMAND_OBJECT("frame", CommandObjectMultiwordFrame); Index: lldb/source/Commands/Options.td =================================================================== --- lldb/source/Commands/Options.td +++ lldb/source/Commands/Options.td @@ -343,6 +343,11 @@ Desc<"Force disassembly of large functions.">; } +let Command = "diagnostics dump" in { + def diagnostics_dump_directory : Option<"directory", "d">, Group<1>, + Arg<"Path">, Desc<"Dump the diagnostics to the given directory.">; +} + let Command = "expression" in { def expression_options_all_threads : Option<"all-threads", "a">, Groups<[1,2]>, Arg<"Boolean">, Desc<"Should we run all threads if the " Index: lldb/source/Commands/CommandObjectDiagnostics.h =================================================================== --- /dev/null +++ lldb/source/Commands/CommandObjectDiagnostics.h @@ -0,0 +1,29 @@ +//===-- CommandObjectDiagnostics.h ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTDIAGNOSTICS_H +#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTDIAGNOSTICS_H + +#include "lldb/Interpreter/CommandObjectMultiword.h" + +namespace lldb_private { + +class CommandObjectDiagnostics : public CommandObjectMultiword { +public: + CommandObjectDiagnostics(CommandInterpreter &interpreter); + ~CommandObjectDiagnostics() override; + +private: + CommandObjectDiagnostics(const CommandObjectDiagnostics &) = delete; + const CommandObjectDiagnostics & + operator=(const CommandObjectDiagnostics &) = delete; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_COMMANDS_COMMANDOBJECTDIAGNOSTICS_H Index: lldb/source/Commands/CommandObjectDiagnostics.cpp =================================================================== --- /dev/null +++ lldb/source/Commands/CommandObjectDiagnostics.cpp @@ -0,0 +1,114 @@ +//===-- CommandObjectDiagnostics.cpp --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectDiagnostics.h" +#include "lldb/Host/OptionParser.h" +#include "lldb/Interpreter/CommandOptionArgumentTable.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionValueEnumeration.h" +#include "lldb/Interpreter/OptionValueUInt64.h" +#include "lldb/Interpreter/Options.h" +#include "lldb/Utility/Diagnostics.h" + +using namespace lldb; +using namespace lldb_private; + +#define LLDB_OPTIONS_diagnostics_dump +#include "CommandOptions.inc" + +class CommandObjectDiagnosticsDump : public CommandObjectParsed { +public: + // Constructors and Destructors + CommandObjectDiagnosticsDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "diagnostics dump", + "Dump diagnostics to disk", nullptr) {} + + ~CommandObjectDiagnosticsDump() override = default; + + class CommandOptions : public Options { + public: + CommandOptions() = default; + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'd': + directory.SetDirectory(option_arg); + break; + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + directory.Clear(); + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_diagnostics_dump_options); + } + + FileSpec directory; + }; + + Options *GetOptions() override { return &m_options; } + +protected: + llvm::Expected<FileSpec> GetDirectory() { + if (m_options.directory) { + auto ec = + llvm::sys::fs::create_directories(m_options.directory.GetPath()); + if (ec) + return llvm::errorCodeToError(ec); + return m_options.directory; + } + return Diagnostics::CreateUniqueDirectory(); + } + + bool DoExecute(Args &args, CommandReturnObject &result) override { + llvm::Expected<FileSpec> directory = GetDirectory(); + + if (!directory) { + result.AppendError(llvm::toString(directory.takeError())); + return result.Succeeded(); + } + + llvm::Error error = Diagnostics::Instance().Create(*directory); + if (error) { + result.AppendErrorWithFormat("failed to write diagnostics to %s", + directory->GetPath().c_str()); + result.AppendError(llvm::toString(std::move(error))); + return result.Succeeded(); + } + + result.GetOutputStream() << "diagnostics written to " << *directory << '\n'; + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + + CommandOptions m_options; +}; + +CommandObjectDiagnostics::CommandObjectDiagnostics( + CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "diagnostics", + "Commands controlling LLDB diagnostics.", + "diagnostics <subcommand> [<command-options>]") { + LoadSubCommand( + "dump", CommandObjectSP(new CommandObjectDiagnosticsDump(interpreter))); +} + +CommandObjectDiagnostics::~CommandObjectDiagnostics() = default; Index: lldb/source/Commands/CMakeLists.txt =================================================================== --- lldb/source/Commands/CMakeLists.txt +++ lldb/source/Commands/CMakeLists.txt @@ -8,6 +8,7 @@ CommandObjectBreakpoint.cpp CommandObjectBreakpointCommand.cpp CommandObjectCommands.cpp + CommandObjectDiagnostics.cpp CommandObjectDisassemble.cpp CommandObjectExpression.cpp CommandObjectFrame.cpp Index: lldb/include/lldb/Utility/Diagnostics.h =================================================================== --- lldb/include/lldb/Utility/Diagnostics.h +++ lldb/include/lldb/Utility/Diagnostics.h @@ -34,7 +34,10 @@ llvm::Error Create(const FileSpec &dir); /// Gather diagnostics and print a message to the given output stream. + /// @{ bool Dump(llvm::raw_ostream &stream); + bool Dump(llvm::raw_ostream &stream, const FileSpec &dir); + /// @} using Callback = std::function<llvm::Error(const FileSpec &)>; @@ -44,6 +47,9 @@ static void Initialize(); static void Terminate(); + /// Create a unique diagnostic directory. + static llvm::Expected<FileSpec> CreateUniqueDirectory(); + private: static llvm::Optional<Diagnostics> &InstanceImpl();
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits