Index: lldb/include/lldb/Core/Debugger.h =================================================================== --- lldb/include/lldb/Core/Debugger.h +++ lldb/include/lldb/Core/Debugger.h @@ -425,6 +425,28 @@ llvm::Optional debugger_id = llvm::None, std::once_flag *once = nullptr); + /// Report info events. + /// + /// Progress events will be delivered to any debuggers that have listeners + /// for the eBroadcastBitError. + /// + /// \param[in] message + /// The error message to be reported. + /// + /// \param [in] debugger_id + /// If this optional parameter has a value, it indicates the unique + /// debugger identifier that this progress should be delivered to. If this + /// optional parameter does not have a value, the progress will be + /// delivered to all debuggers. + /// + /// \param [in] once + /// If a pointer is passed to a std::once_flag, then it will be used to + /// ensure the given error is only broadcast once. + static void + ReportInfo(std::string message, + llvm::Optional debugger_id = llvm::None, + std::once_flag *once = nullptr); + static void ReportSymbolChange(const ModuleSpec &module_spec); protected: Index: lldb/include/lldb/Core/DebuggerEvents.h =================================================================== --- lldb/include/lldb/Core/DebuggerEvents.h +++ lldb/include/lldb/Core/DebuggerEvents.h @@ -52,6 +52,7 @@ class DiagnosticEventData : public EventData { public: enum class Type { + Info, Warning, Error, }; Index: lldb/include/lldb/Utility/Diagnostics.h =================================================================== --- lldb/include/lldb/Utility/Diagnostics.h +++ lldb/include/lldb/Utility/Diagnostics.h @@ -39,6 +39,8 @@ bool Dump(llvm::raw_ostream &stream, const FileSpec &dir); /// @} + void Report(llvm::StringRef message); + using Callback = std::function; void AddCallback(Callback callback); @@ -53,6 +55,10 @@ private: static llvm::Optional &InstanceImpl(); + llvm::Error DumpAlwaysOnLog(const FileSpec &dir) const; + + RotatingLogHandler m_log_handler; + llvm::SmallVector m_callbacks; std::mutex m_callbacks_mutex; }; Index: lldb/source/Core/Debugger.cpp =================================================================== --- lldb/source/Core/Debugger.cpp +++ lldb/source/Core/Debugger.cpp @@ -1311,6 +1311,9 @@ bool debugger_specific) { uint32_t event_type = 0; switch (type) { + case DiagnosticEventData::Type::Info: + assert(false && "DiagnosticEventData::Type::Info should not be broadcast"); + return; case DiagnosticEventData::Type::Warning: event_type = Debugger::eBroadcastBitWarning; break; @@ -1339,6 +1342,12 @@ llvm::Optional debugger_id, std::once_flag *once) { auto ReportDiagnosticLambda = [&]() { + Diagnostics::Instance().Report(message); + + // We don't broadcast info events. + if (type == DiagnosticEventData::Type::Info) + return; + // Check if this diagnostic is for a specific debugger. if (debugger_id) { // It is debugger specific, grab it and deliver the event if the debugger @@ -1377,6 +1386,13 @@ debugger_id, once); } +void Debugger::ReportInfo(std::string message, + llvm::Optional debugger_id, + std::once_flag *once) { + ReportDiagnosticImpl(DiagnosticEventData::Type::Info, std::move(message), + debugger_id, once); +} + void Debugger::ReportSymbolChange(const ModuleSpec &module_spec) { if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { std::lock_guard guard(*g_debugger_list_mutex_ptr); Index: lldb/source/Core/DebuggerEvents.cpp =================================================================== --- lldb/source/Core/DebuggerEvents.cpp +++ lldb/source/Core/DebuggerEvents.cpp @@ -51,6 +51,8 @@ llvm::StringRef DiagnosticEventData::GetPrefix() const { switch (m_type) { + case Type::Info: + return "info"; case Type::Warning: return "warning"; case Type::Error: Index: lldb/source/Utility/Diagnostics.cpp =================================================================== --- lldb/source/Utility/Diagnostics.cpp +++ lldb/source/Utility/Diagnostics.cpp @@ -17,6 +17,8 @@ using namespace lldb; using namespace llvm; +static constexpr size_t g_num_log_messages = 100; + void Diagnostics::Initialize() { lldbassert(!InstanceImpl() && "Already initialized."); InstanceImpl().emplace(); @@ -34,7 +36,7 @@ Diagnostics &Diagnostics::Instance() { return *InstanceImpl(); } -Diagnostics::Diagnostics() {} +Diagnostics::Diagnostics() : m_log_handler(g_num_log_messages) {} Diagnostics::~Diagnostics() {} @@ -58,8 +60,7 @@ stream << "LLDB diagnostics written to " << dir.GetPath() << "\n"; stream << "Please include the directory content when filing a bug report\n"; - Error error = Create(dir); - if (error) { + if (Error error = Create(dir)) { stream << toString(std::move(error)) << '\n'; return false; } @@ -77,9 +78,27 @@ } Error Diagnostics::Create(const FileSpec &dir) { + if (Error err = DumpAlwaysOnLog(dir)) + return err; + for (Callback c : m_callbacks) { if (Error err = c(dir)) return err; } + + return Error::success(); +} + +llvm::Error Diagnostics::DumpAlwaysOnLog(const FileSpec &dir) const { + FileSpec log_file = dir.CopyByAppendingPathComponent("diagnostics.log"); + std::error_code ec; + llvm::raw_fd_ostream stream(log_file.GetPath(), ec, llvm::sys::fs::OF_None); + if (ec) + return errorCodeToError(ec); + m_log_handler.Dump(stream); return Error::success(); } + +void Diagnostics::Report(llvm::StringRef message) { + m_log_handler.Emit(message); +} Index: lldb/test/Shell/Diagnostics/TestDiagnosticsLog.test =================================================================== --- /dev/null +++ lldb/test/Shell/Diagnostics/TestDiagnosticsLog.test @@ -0,0 +1,33 @@ +# RUN: yaml2obj %s -o %t +# RUN: mkdir -p %t.diags +# RUN: %lldb -c %t -o 'diagnostics dump -d %t.diags' 2> %t.stderr + +# RUN: cat %t.stderr | FileCheck %s --check-prefix ERROR +# RUN: cat %t.diags/diagnostics.log | FileCheck %s --check-prefix ERROR + +# ERROR: unable to retrieve process ID from minidump file, setting process ID to 1 + +--- !minidump +Streams: + - Type: ThreadList + Threads: + - Thread Id: 0x00003E81 + Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Stack: + Start of Memory Range: 0x00007FFCEB34A000 + Content: '' + - Type: ModuleList + Modules: + - Base of Image: 0x0000000000400000 + Size of Image: 0x00017000 + Module Name: 'a.out' + CodeView Record: '' + - Type: SystemInfo + Processor Arch: AMD64 + Platform ID: Linux + CSD Version: 'Linux 3.13' + CPU: + Vendor ID: GenuineIntel + Version Info: 0x00000000 + Feature Info: 0x00000000 +...