diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Utility/Log.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Utility/Log.cpp | 131 |
1 files changed, 106 insertions, 25 deletions
diff --git a/contrib/llvm-project/lldb/source/Utility/Log.cpp b/contrib/llvm-project/lldb/source/Utility/Log.cpp index d229538073d1..67edb15ba684 100644 --- a/contrib/llvm-project/lldb/source/Utility/Log.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Log.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" @@ -34,6 +35,11 @@ using namespace lldb_private; +char LogHandler::ID; +char StreamLogHandler::ID; +char CallbackLogHandler::ID; +char RotatingLogHandler::ID; + llvm::ManagedStatic<Log::ChannelMap> Log::g_channel_map; void Log::ForEachCategory( @@ -84,14 +90,14 @@ uint32_t Log::GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type & return flags; } -void Log::Enable(const std::shared_ptr<llvm::raw_ostream> &stream_sp, +void Log::Enable(const std::shared_ptr<LogHandler> &handler_sp, uint32_t options, uint32_t flags) { llvm::sys::ScopedWriter lock(m_mutex); MaskType mask = m_mask.fetch_or(flags, std::memory_order_relaxed); if (mask | flags) { m_options.store(options, std::memory_order_relaxed); - m_stream_sp = stream_sp; + m_handler = handler_sp; m_channel.log_ptr.store(this, std::memory_order_relaxed); } } @@ -101,11 +107,21 @@ void Log::Disable(uint32_t flags) { MaskType mask = m_mask.fetch_and(~flags, std::memory_order_relaxed); if (!(mask & ~flags)) { - m_stream_sp.reset(); + m_handler.reset(); m_channel.log_ptr.store(nullptr, std::memory_order_relaxed); } } +bool Log::Dump(llvm::raw_ostream &output_stream) { + llvm::sys::ScopedReader lock(m_mutex); + if (RotatingLogHandler *handler = + llvm::dyn_cast_or_null<RotatingLogHandler>(m_handler.get())) { + handler->Dump(output_stream); + return true; + } + return false; +} + const Flags Log::GetOptions() const { return m_options.load(std::memory_order_relaxed); } @@ -178,10 +194,6 @@ void Log::Warning(const char *format, ...) { Printf("warning: %s", Content.c_str()); } -void Log::Initialize() { - InitializeLldbChannel(); -} - void Log::Register(llvm::StringRef name, Channel &channel) { auto iter = g_channel_map->try_emplace(name, channel); assert(iter.second == true); @@ -195,10 +207,10 @@ void Log::Unregister(llvm::StringRef name) { g_channel_map->erase(iter); } -bool Log::EnableLogChannel( - const std::shared_ptr<llvm::raw_ostream> &log_stream_sp, - uint32_t log_options, llvm::StringRef channel, - llvm::ArrayRef<const char *> categories, llvm::raw_ostream &error_stream) { +bool Log::EnableLogChannel(const std::shared_ptr<LogHandler> &log_handler_sp, + uint32_t log_options, llvm::StringRef channel, + llvm::ArrayRef<const char *> categories, + llvm::raw_ostream &error_stream) { auto iter = g_channel_map->find(channel); if (iter == g_channel_map->end()) { error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel); @@ -207,7 +219,7 @@ bool Log::EnableLogChannel( uint32_t flags = categories.empty() ? iter->second.m_channel.default_flags : GetFlags(error_stream, *iter, categories); - iter->second.Enable(log_stream_sp, log_options, flags); + iter->second.Enable(log_handler_sp, log_options, flags); return true; } @@ -226,6 +238,22 @@ bool Log::DisableLogChannel(llvm::StringRef channel, return true; } +bool Log::DumpLogChannel(llvm::StringRef channel, + llvm::raw_ostream &output_stream, + llvm::raw_ostream &error_stream) { + auto iter = g_channel_map->find(channel); + if (iter == g_channel_map->end()) { + error_stream << llvm::formatv("Invalid log channel '{0}'.\n", channel); + return false; + } + if (!iter->second.Dump(output_stream)) { + error_stream << llvm::formatv( + "log channel '{0}' does not support dumping.\n", channel); + return false; + } + return true; +} + bool Log::ListChannelCategories(llvm::StringRef channel, llvm::raw_ostream &stream) { auto ch = g_channel_map->find(channel); @@ -318,20 +346,10 @@ void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file, void Log::WriteMessage(const std::string &message) { // Make a copy of our stream shared pointer in case someone disables our log // while we are logging and releases the stream - auto stream_sp = GetStream(); - if (!stream_sp) + auto handler_sp = GetHandler(); + if (!handler_sp) return; - - Flags options = GetOptions(); - if (options.Test(LLDB_LOG_OPTION_THREADSAFE)) { - static std::recursive_mutex g_LogThreadedMutex; - std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex); - *stream_sp << message; - stream_sp->flush(); - } else { - *stream_sp << message; - stream_sp->flush(); - } + handler_sp->Emit(message); } void Log::Format(llvm::StringRef file, llvm::StringRef function, @@ -342,3 +360,66 @@ void Log::Format(llvm::StringRef file, llvm::StringRef function, message << payload << "\n"; WriteMessage(message.str()); } + +StreamLogHandler::StreamLogHandler(int fd, bool should_close, + size_t buffer_size) + : m_stream(fd, should_close, buffer_size == 0) { + if (buffer_size > 0) + m_stream.SetBufferSize(buffer_size); +} + +StreamLogHandler::~StreamLogHandler() { Flush(); } + +void StreamLogHandler::Flush() { + std::lock_guard<std::mutex> guard(m_mutex); + m_stream.flush(); +} + +void StreamLogHandler::Emit(llvm::StringRef message) { + if (m_stream.GetBufferSize() > 0) { + std::lock_guard<std::mutex> guard(m_mutex); + m_stream << message; + } else { + m_stream << message; + } +} + +CallbackLogHandler::CallbackLogHandler(lldb::LogOutputCallback callback, + void *baton) + : m_callback(callback), m_baton(baton) {} + +void CallbackLogHandler::Emit(llvm::StringRef message) { + m_callback(message.data(), m_baton); +} + +RotatingLogHandler::RotatingLogHandler(size_t size) + : m_messages(std::make_unique<std::string[]>(size)), m_size(size) {} + +void RotatingLogHandler::Emit(llvm::StringRef message) { + std::lock_guard<std::mutex> guard(m_mutex); + ++m_total_count; + const size_t index = m_next_index; + m_next_index = NormalizeIndex(index + 1); + m_messages[index] = message.str(); +} + +size_t RotatingLogHandler::NormalizeIndex(size_t i) const { return i % m_size; } + +size_t RotatingLogHandler::GetNumMessages() const { + return m_total_count < m_size ? m_total_count : m_size; +} + +size_t RotatingLogHandler::GetFirstMessageIndex() const { + return m_total_count < m_size ? 0 : m_next_index; +} + +void RotatingLogHandler::Dump(llvm::raw_ostream &stream) const { + std::lock_guard<std::mutex> guard(m_mutex); + const size_t start_idx = GetFirstMessageIndex(); + const size_t stop_idx = start_idx + GetNumMessages(); + for (size_t i = start_idx; i < stop_idx; ++i) { + const size_t idx = NormalizeIndex(i); + stream << m_messages[idx]; + } + stream.flush(); +} |