Index: lldb/include/lldb/Utility/Diagnostics.h =================================================================== --- lldb/include/lldb/Utility/Diagnostics.h +++ lldb/include/lldb/Utility/Diagnostics.h @@ -46,6 +46,11 @@ private: static llvm::Optional &InstanceImpl(); + static const size_t g_log_messages; + + llvm::Error DumpAlwaysOnLog(const FileSpec &dir) const; + + std::shared_ptr m_always_on_log_handler; llvm::SmallVector m_callbacks; std::mutex m_callbacks_mutex; Index: lldb/include/lldb/Utility/LLDBLog.h =================================================================== --- lldb/include/lldb/Utility/LLDBLog.h +++ lldb/include/lldb/Utility/LLDBLog.h @@ -48,7 +48,8 @@ Unwind = Log::ChannelFlag<29>, Watchpoints = Log::ChannelFlag<30>, OnDemand = Log::ChannelFlag<31>, - LLVM_MARK_AS_BITMASK_ENUM(OnDemand), + AlwaysOn = Log::ChannelFlag<32>, + LLVM_MARK_AS_BITMASK_ENUM(AlwaysOn), }; LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); Index: lldb/include/lldb/Utility/Log.h =================================================================== --- lldb/include/lldb/Utility/Log.h +++ lldb/include/lldb/Utility/Log.h @@ -131,11 +131,14 @@ llvm::StringLiteral name; llvm::StringLiteral description; MaskType flag; + bool internal; template constexpr Category(llvm::StringLiteral name, - llvm::StringLiteral description, Cat mask) - : name(name), description(description), flag(MaskType(mask)) { + llvm::StringLiteral description, Cat mask, + bool internal = false) + : name(name), description(description), flag(MaskType(mask)), + internal(internal) { static_assert( std::is_same>::value); } Index: lldb/source/Utility/Diagnostics.cpp =================================================================== --- lldb/source/Utility/Diagnostics.cpp +++ lldb/source/Utility/Diagnostics.cpp @@ -8,6 +8,7 @@ #include "lldb/Utility/Diagnostics.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" @@ -17,6 +18,8 @@ using namespace lldb; using namespace llvm; +const size_t Diagnostics::g_log_messages = 100; + void Diagnostics::Initialize() { lldbassert(!InstanceImpl() && "Already initialized."); InstanceImpl().emplace(); @@ -34,9 +37,18 @@ Diagnostics &Diagnostics::Instance() { return *InstanceImpl(); } -Diagnostics::Diagnostics() {} +Diagnostics::Diagnostics() + : m_always_on_log_handler( + std::make_shared(g_log_messages)) { + const uint32_t log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME; + Log::EnableLogChannel(m_always_on_log_handler, log_options, "lldb", + {"always-on"}, llvm::nulls()); + AddCallback([&](const FileSpec &dir) { return DumpAlwaysOnLog(dir); }); +} -Diagnostics::~Diagnostics() {} +Diagnostics::~Diagnostics() { + Log::DisableLogChannel("lldb", {"always-on"}, llvm::nulls()); +} void Diagnostics::AddCallback(Callback callback) { std::lock_guard guard(m_callbacks_mutex); @@ -66,9 +78,22 @@ } Error Diagnostics::Create(const FileSpec &dir) { + LLDB_LOG(GetLog(LLDBLog::AlwaysOn), "Dumping {0} diagnostics to '{1}'", + m_callbacks.size(), dir.GetPath()); + 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("always-on.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_always_on_log_handler->Dump(stream); + return Error::success(); +} Index: lldb/source/Utility/LLDBLog.cpp =================================================================== --- lldb/source/Utility/LLDBLog.cpp +++ lldb/source/Utility/LLDBLog.cpp @@ -63,6 +63,10 @@ {{"on-demand"}, {"log symbol on-demand related activities"}, LLDBLog::OnDemand}, + {{"always-on"}, + {"log pertinent activities for diagnosing issues in the debugger"}, + LLDBLog::AlwaysOn, + /*internal=*/true}, }; static Log::Channel g_log_channel(g_categories, Index: lldb/source/Utility/Log.cpp =================================================================== --- lldb/source/Utility/Log.cpp +++ lldb/source/Utility/Log.cpp @@ -48,7 +48,8 @@ lambda("all", "all available logging categories"); lambda("default", "default set of logging categories"); for (const auto &category : entry.second.m_channel.categories) - lambda(category.name, category.description); + if (!category.internal) + lambda(category.name, category.description); } void Log::ListCategories(llvm::raw_ostream &stream,