aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Utility/Log.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Utility/Log.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Utility/Log.cpp131
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();
+}