[Lldb-commits] [lldb] r295442 - Reapply "Refactor log channel registration mechanism"
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 17 05:27:43 PST 2017
Author: labath
Date: Fri Feb 17 07:27:42 2017
New Revision: 295442
URL: http://llvm.org/viewvc/llvm-project?rev=295442&view=rev
Log:
Reapply "Refactor log channel registration mechanism"
Changes wrt. previous version:
- add #include <atomic>: fix build on windows
- add extra {} around the string literals used to initialize
llvm::StringLiteral: fix gcc build
Modified:
lldb/trunk/include/lldb/Core/Log.h
lldb/trunk/include/lldb/Core/PluginManager.h
lldb/trunk/include/lldb/lldb-forward.h
lldb/trunk/include/lldb/lldb-private-interfaces.h
lldb/trunk/source/Commands/CommandObjectLog.cpp
lldb/trunk/source/Core/Log.cpp
lldb/trunk/source/Core/PluginManager.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/trunk/unittests/Core/LogTest.cpp
Modified: lldb/trunk/include/lldb/Core/Log.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Log.h?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Log.h (original)
+++ lldb/trunk/include/lldb/Core/Log.h Fri Feb 17 07:27:42 2017
@@ -12,7 +12,6 @@
// Project includes
#include "lldb/Core/Logging.h"
-#include "lldb/Core/PluginInterface.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Flags.h"
#include "lldb/lldb-private.h"
@@ -20,6 +19,7 @@
// Other libraries and framework includes
#include "llvm/Support/FormatVariadic.h"
// C++ Includes
+#include <atomic>
#include <cstdarg>
#include <cstdint>
// C Includes
@@ -44,6 +44,53 @@ namespace lldb_private {
class Log final {
public:
+ // Description of a log channel category.
+ struct Category {
+ llvm::StringLiteral name;
+ llvm::StringLiteral description;
+ uint32_t flag;
+ };
+
+ // This class describes a log channel. It also encapsulates the behavior
+ // necessary to enable a log channel in an atomic manner.
+ class Channel {
+ std::atomic<Log *> log_ptr;
+
+ public:
+ const llvm::ArrayRef<Category> categories;
+ const uint32_t default_flags;
+
+ constexpr Channel(llvm::ArrayRef<Log::Category> categories,
+ uint32_t default_flags)
+ : log_ptr(nullptr), categories(categories),
+ default_flags(default_flags) {}
+
+ // This function is safe to call at any time
+ // FIXME: Not true yet, mask access is not atomic
+ Log *GetLogIfAll(uint32_t mask) {
+ Log *log = log_ptr.load(std::memory_order_acquire);
+ if (log && log->GetMask().AllSet(mask))
+ return log;
+ return nullptr;
+ }
+
+ // This function is safe to call at any time
+ // FIXME: Not true yet, mask access is not atomic
+ Log *GetLogIfAny(uint32_t mask) {
+ Log *log = log_ptr.load(std::memory_order_acquire);
+ if (log && log->GetMask().AnySet(mask))
+ return log;
+ return nullptr;
+ }
+
+ // Calls to Enable and disable need to be serialized externally.
+ void Enable(Log &log, const std::shared_ptr<llvm::raw_ostream> &stream_sp,
+ uint32_t flags);
+
+ // Calls to Enable and disable need to be serialized externally.
+ void Disable(uint32_t flags);
+ };
+
//------------------------------------------------------------------
// Callback definitions for abstracted plug-in log access.
//------------------------------------------------------------------
@@ -63,6 +110,9 @@ public:
//------------------------------------------------------------------
// Static accessors for logging channels
//------------------------------------------------------------------
+ static void Register(llvm::StringRef name, Channel &channel);
+ static void Unregister(llvm::StringRef name);
+
static void RegisterLogChannel(const ConstString &channel,
const Log::Callbacks &log_callbacks);
@@ -73,13 +123,13 @@ public:
static bool
EnableLogChannel(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options, const char *channel,
+ uint32_t log_options, llvm::StringRef channel,
const char **categories, Stream &error_stream);
- static void
- EnableAllLogChannels(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options, const char **categories,
- Stream *feedback_strm);
+ static bool DisableLogChannel(llvm::StringRef channel,
+ const char **categories, Stream &error_stream);
+
+ static bool ListChannelCategories(llvm::StringRef channel, Stream &stream);
static void DisableAllLogChannels(Stream *feedback_strm);
@@ -90,12 +140,6 @@ public:
static void Terminate();
//------------------------------------------------------------------
- // Auto completion
- //------------------------------------------------------------------
- static void AutoCompleteChannelName(const char *channel_name,
- StringList &matches);
-
- //------------------------------------------------------------------
// Member functions
//------------------------------------------------------------------
Log();
@@ -162,34 +206,6 @@ private:
const llvm::formatv_object_base &payload);
};
-class LogChannel : public PluginInterface {
-public:
- LogChannel();
-
- ~LogChannel() override;
-
- static lldb::LogChannelSP FindPlugin(const char *plugin_name);
-
- // categories is an array of chars that ends with a NULL element.
- virtual void Disable(const char **categories, Stream *feedback_strm) = 0;
-
- virtual bool
- Enable(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options,
- Stream *feedback_strm, // Feedback stream for argument errors etc
- const char **categories) = 0; // The categories to enable within this
- // logging stream, if empty, enable
- // default set
-
- virtual void ListCategories(Stream *strm) = 0;
-
-protected:
- std::unique_ptr<Log> m_log_ap;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(LogChannel);
-};
-
} // namespace lldb_private
#define LLDB_LOG(log, ...) \
Modified: lldb/trunk/include/lldb/Core/PluginManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/PluginManager.h?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/PluginManager.h (original)
+++ lldb/trunk/include/lldb/Core/PluginManager.h Fri Feb 17 07:27:42 2017
@@ -210,22 +210,6 @@ public:
GetObjectContainerGetModuleSpecificationsCallbackAtIndex(uint32_t idx);
//------------------------------------------------------------------
- // LogChannel
- //------------------------------------------------------------------
- static bool RegisterPlugin(const ConstString &name, const char *description,
- LogChannelCreateInstance create_callback);
-
- static bool UnregisterPlugin(LogChannelCreateInstance create_callback);
-
- static LogChannelCreateInstance
- GetLogChannelCreateCallbackAtIndex(uint32_t idx);
-
- static LogChannelCreateInstance
- GetLogChannelCreateCallbackForPluginName(const ConstString &name);
-
- static const char *GetLogChannelCreateNameAtIndex(uint32_t idx);
-
- //------------------------------------------------------------------
// Platform
//------------------------------------------------------------------
static bool
Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Fri Feb 17 07:27:42 2017
@@ -127,7 +127,6 @@ class MemoryRegionInfo;
class LineTable;
class Listener;
class Log;
-class LogChannel;
class Mangled;
class Materializer;
class MemoryHistory;
@@ -362,7 +361,6 @@ typedef std::unique_ptr<lldb_private::Sy
typedef std::shared_ptr<lldb_private::LineTable> LineTableSP;
typedef std::shared_ptr<lldb_private::Listener> ListenerSP;
typedef std::weak_ptr<lldb_private::Listener> ListenerWP;
-typedef std::shared_ptr<lldb_private::LogChannel> LogChannelSP;
typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP;
typedef std::shared_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoSP;
typedef std::unique_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoUP;
Modified: lldb/trunk/include/lldb/lldb-private-interfaces.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-interfaces.h?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-interfaces.h (original)
+++ lldb/trunk/include/lldb/lldb-private-interfaces.h Fri Feb 17 07:27:42 2017
@@ -45,7 +45,6 @@ typedef ObjectFile *(*ObjectFileCreateMe
const lldb::ProcessSP &process_sp, lldb::addr_t offset);
typedef bool (*ObjectFileSaveCore)(const lldb::ProcessSP &process_sp,
const FileSpec &outfile, Error &error);
-typedef LogChannel *(*LogChannelCreateInstance)();
typedef EmulateInstruction *(*EmulateInstructionCreateInstance)(
const ArchSpec &arch, InstructionType inst_type);
typedef OperatingSystem *(*OperatingSystemCreateInstance)(Process *process,
Modified: lldb/trunk/source/Commands/CommandObjectLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectLog.cpp?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectLog.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectLog.cpp Fri Feb 17 07:27:42 2017
@@ -227,25 +227,15 @@ protected:
return false;
}
- Log::Callbacks log_callbacks;
-
const std::string channel = args[0].ref;
args.Shift(); // Shift off the channel
- if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
- log_callbacks.disable(args.GetConstArgumentVector(),
- &result.GetErrorStream());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else if (channel == "all") {
+ if (channel == "all") {
Log::DisableAllLogChannels(&result.GetErrorStream());
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
} else {
- LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.data()));
- if (log_channel_sp) {
- log_channel_sp->Disable(args.GetConstArgumentVector(),
- &result.GetErrorStream());
+ if (Log::DisableLogChannel(channel, args.GetConstArgumentVector(),
+ result.GetErrorStream()))
result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else
- result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
- channel.data());
}
return result.Succeeded();
}
@@ -284,26 +274,12 @@ protected:
Log::ListAllLogChannels(&result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
- for (auto &entry : args.entries()) {
- Log::Callbacks log_callbacks;
-
- if (Log::GetLogChannelCallbacks(ConstString(entry.ref),
- log_callbacks)) {
- log_callbacks.list_categories(&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else if (entry.ref == "all") {
- Log::ListAllLogChannels(&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- LogChannelSP log_channel_sp(LogChannel::FindPlugin(entry.c_str()));
- if (log_channel_sp) {
- log_channel_sp->ListCategories(&result.GetOutputStream());
- result.SetStatus(eReturnStatusSuccessFinishNoResult);
- } else
- result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
- entry.c_str());
- }
- }
+ bool success = true;
+ for (const auto &entry : args.entries())
+ success = success && Log::ListChannelCategories(
+ entry.ref, result.GetOutputStream());
+ if (success)
+ result.SetStatus(eReturnStatusSuccessFinishResult);
}
return result.Succeeded();
}
Modified: lldb/trunk/source/Core/Log.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Log.cpp?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/source/Core/Log.cpp (original)
+++ lldb/trunk/source/Core/Log.cpp Fri Feb 17 07:27:42 2017
@@ -18,8 +18,10 @@
#include "lldb/Utility/StreamString.h"
// Other libraries and framework includes
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Chrono.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
@@ -36,6 +38,76 @@
using namespace lldb;
using namespace lldb_private;
+namespace {
+ struct ChannelAndLog {
+ Log log;
+ Log::Channel &channel;
+
+ ChannelAndLog(Log::Channel &channel) : channel(channel) {}
+ };
+ typedef llvm::StringMap<ChannelAndLog> ChannelMap;
+}
+
+static llvm::ManagedStatic<ChannelMap> g_channel_map;
+
+static void ListCategories(Stream &stream, const ChannelMap::value_type &entry) {
+ stream.Format("Logging categories for '{0}':\n", entry.first());
+ stream.Format(" all - all available logging categories\n");
+ stream.Format(" default - default set of logging categories\n");
+ for (const auto &category : entry.second.channel.categories)
+ stream.Format(" {0} - {1}\n", category.name, category.description);
+}
+
+static uint32_t GetFlags(Stream &stream, const ChannelMap::value_type &entry,
+ const char **categories) {
+ bool list_categories = false;
+ uint32_t flags = 0;
+ for (size_t i = 0; categories[i]; ++i) {
+ if (llvm::StringRef("all").equals_lower(categories[i])) {
+ flags |= UINT32_MAX;
+ continue;
+ }
+ if (llvm::StringRef("default").equals_lower(categories[i])) {
+ flags |= entry.second.channel.default_flags;
+ continue;
+ }
+ auto cat = llvm::find_if(entry.second.channel.categories,
+ [&](const Log::Category &c) {
+ return c.name.equals_lower(categories[i]);
+ });
+ if (cat != entry.second.channel.categories.end()) {
+ flags |= cat->flag;
+ continue;
+ }
+ stream.Format("error: unrecognized log category '{0}'\n", categories[i]);
+ list_categories = true;
+ }
+ if (list_categories)
+ ListCategories(stream, entry);
+ return flags;
+}
+
+void Log::Channel::Enable(Log &log,
+ const std::shared_ptr<llvm::raw_ostream> &stream_sp,
+ uint32_t flags) {
+ log.GetMask().Set(flags);
+ if (log.GetMask().Get()) {
+ log.SetStream(stream_sp);
+ log_ptr.store(&log, std::memory_order_release);
+ }
+}
+
+void Log::Channel::Disable(uint32_t flags) {
+ Log *log = log_ptr.load(std::memory_order_acquire);
+ if (!log)
+ return;
+ log->GetMask().Clear(flags);
+ if (!log->GetMask().Get()) {
+ log->SetStream(nullptr);
+ log_ptr.store(nullptr, std::memory_order_release);
+ }
+}
+
Log::Log() : m_stream_sp(), m_options(0), m_mask_bits(0) {}
Log::Log(const std::shared_ptr<llvm::raw_ostream> &stream_sp)
@@ -152,9 +224,6 @@ void Log::Warning(const char *format, ..
typedef std::map<ConstString, Log::Callbacks> CallbackMap;
typedef CallbackMap::iterator CallbackMapIter;
-typedef std::map<ConstString, LogChannelSP> LogChannelMap;
-typedef LogChannelMap::iterator LogChannelMapIter;
-
// Surround our callback map with a singleton function so we don't have any
// global initializers.
static CallbackMap &GetCallbackMap() {
@@ -162,9 +231,17 @@ static CallbackMap &GetCallbackMap() {
return g_callback_map;
}
-static LogChannelMap &GetChannelMap() {
- static LogChannelMap g_channel_map;
- return g_channel_map;
+void Log::Register(llvm::StringRef name, Channel &channel) {
+ auto iter = g_channel_map->try_emplace(name, channel);
+ assert(iter.second == true);
+ (void)iter;
+}
+
+void Log::Unregister(llvm::StringRef name) {
+ auto iter = g_channel_map->find(name);
+ assert(iter != g_channel_map->end());
+ iter->second.channel.Disable(UINT32_MAX);
+ g_channel_map->erase(iter);
}
void Log::RegisterLogChannel(const ConstString &channel,
@@ -190,7 +267,7 @@ bool Log::GetLogChannelCallbacks(const C
bool Log::EnableLogChannel(
const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options, const char *channel, const char **categories,
+ uint32_t log_options, llvm::StringRef channel, const char **categories,
Stream &error_stream) {
Log::Callbacks log_callbacks;
if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
@@ -198,52 +275,52 @@ bool Log::EnableLogChannel(
return true;
}
- LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel));
- if (log_channel_sp) {
- if (log_channel_sp->Enable(log_stream_sp, log_options, &error_stream,
- categories)) {
- return true;
- } else {
- error_stream.Printf("Invalid log channel '%s'.\n", channel);
- return false;
- }
- } else {
- error_stream.Printf("Invalid log channel '%s'.\n", channel);
+ auto iter = g_channel_map->find(channel);
+ if (iter == g_channel_map->end()) {
+ error_stream.Format("Invalid log channel '{0}'.\n", channel);
return false;
}
+ uint32_t flags = categories && categories[0]
+ ? GetFlags(error_stream, *iter, categories)
+ : iter->second.channel.default_flags;
+ iter->second.channel.Enable(iter->second.log, log_stream_sp, flags);
+ return true;
}
-void Log::EnableAllLogChannels(
- const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options, const char **categories, Stream *feedback_strm) {
- CallbackMap &callback_map = GetCallbackMap();
- CallbackMapIter pos, end = callback_map.end();
-
- for (pos = callback_map.begin(); pos != end; ++pos)
- pos->second.enable(log_stream_sp, log_options, categories, feedback_strm);
+bool Log::DisableLogChannel(llvm::StringRef channel, const char **categories,
+ Stream &error_stream) {
+ Log::Callbacks log_callbacks;
+ if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
+ log_callbacks.disable(categories, &error_stream);
+ return true;
+ }
- LogChannelMap &channel_map = GetChannelMap();
- LogChannelMapIter channel_pos, channel_end = channel_map.end();
- for (channel_pos = channel_map.begin(); channel_pos != channel_end;
- ++channel_pos) {
- channel_pos->second->Enable(log_stream_sp, log_options, feedback_strm,
- categories);
+ auto iter = g_channel_map->find(channel);
+ if (iter == g_channel_map->end()) {
+ error_stream.Format("Invalid log channel '{0}'.\n", channel);
+ return false;
}
+ uint32_t flags = categories && categories[0]
+ ? GetFlags(error_stream, *iter, categories)
+ : UINT32_MAX;
+ iter->second.channel.Disable(flags);
+ return true;
}
-void Log::AutoCompleteChannelName(const char *channel_name,
- StringList &matches) {
- LogChannelMap &map = GetChannelMap();
- LogChannelMapIter pos, end = map.end();
- for (pos = map.begin(); pos != end; ++pos) {
- const char *pos_channel_name = pos->first.GetCString();
- if (channel_name && channel_name[0]) {
- if (NameMatches(channel_name, eNameMatchStartsWith, pos_channel_name)) {
- matches.AppendString(pos_channel_name);
- }
- } else
- matches.AppendString(pos_channel_name);
+bool Log::ListChannelCategories(llvm::StringRef channel, Stream &stream) {
+ Log::Callbacks log_callbacks;
+ if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
+ log_callbacks.list_categories(&stream);
+ return true;
}
+
+ auto ch = g_channel_map->find(channel);
+ if (ch == g_channel_map->end()) {
+ stream.Format("Invalid log channel '{0}'.\n", channel);
+ return false;
+ }
+ ListCategories(stream, *ch);
+ return true;
}
void Log::DisableAllLogChannels(Stream *feedback_strm) {
@@ -254,11 +331,8 @@ void Log::DisableAllLogChannels(Stream *
for (pos = callback_map.begin(); pos != end; ++pos)
pos->second.disable(categories, feedback_strm);
- LogChannelMap &channel_map = GetChannelMap();
- LogChannelMapIter channel_pos, channel_end = channel_map.end();
- for (channel_pos = channel_map.begin(); channel_pos != channel_end;
- ++channel_pos)
- channel_pos->second->Disable(categories, feedback_strm);
+ for (auto &entry : *g_channel_map)
+ entry.second.channel.Disable(UINT32_MAX);
}
void Log::Initialize() {
@@ -270,9 +344,8 @@ void Log::Terminate() { DisableAllLogCha
void Log::ListAllLogChannels(Stream *strm) {
CallbackMap &callback_map = GetCallbackMap();
- LogChannelMap &channel_map = GetChannelMap();
- if (callback_map.empty() && channel_map.empty()) {
+ if (callback_map.empty() && g_channel_map->empty()) {
strm->PutCString("No logging channels are currently registered.\n");
return;
}
@@ -281,17 +354,9 @@ void Log::ListAllLogChannels(Stream *str
for (pos = callback_map.begin(); pos != end; ++pos)
pos->second.list_categories(strm);
- uint32_t idx = 0;
- const char *name;
- for (idx = 0;
- (name = PluginManager::GetLogChannelCreateNameAtIndex(idx)) != nullptr;
- ++idx) {
- LogChannelSP log_channel_sp(LogChannel::FindPlugin(name));
- if (log_channel_sp)
- log_channel_sp->ListCategories(strm);
- }
+ for (const auto &channel : *g_channel_map)
+ ListCategories(*strm, channel);
}
-
bool Log::GetVerbose() const { return m_options.Test(LLDB_LOG_OPTION_VERBOSE); }
void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
@@ -358,33 +423,3 @@ void Log::Format(llvm::StringRef file, l
message << payload << "\n";
WriteMessage(message.str());
}
-
-LogChannelSP LogChannel::FindPlugin(const char *plugin_name) {
- LogChannelSP log_channel_sp;
- LogChannelMap &channel_map = GetChannelMap();
- ConstString log_channel_name(plugin_name);
- LogChannelMapIter pos = channel_map.find(log_channel_name);
- if (pos == channel_map.end()) {
- ConstString const_plugin_name(plugin_name);
- LogChannelCreateInstance create_callback =
- PluginManager::GetLogChannelCreateCallbackForPluginName(
- const_plugin_name);
- if (create_callback) {
- log_channel_sp.reset(create_callback());
- if (log_channel_sp) {
- // Cache the one and only loaded instance of each log channel
- // plug-in after it has been loaded once.
- channel_map[log_channel_name] = log_channel_sp;
- }
- }
- } else {
- // We have already loaded an instance of this log channel class,
- // so just return the cached instance.
- log_channel_sp = pos->second;
- }
- return log_channel_sp;
-}
-
-LogChannel::LogChannel() : m_log_ap() {}
-
-LogChannel::~LogChannel() = default;
Modified: lldb/trunk/source/Core/PluginManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/PluginManager.cpp?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/source/Core/PluginManager.cpp (original)
+++ lldb/trunk/source/Core/PluginManager.cpp Fri Feb 17 07:27:42 2017
@@ -1167,93 +1167,6 @@ PluginManager::GetObjectContainerGetModu
return nullptr;
}
-#pragma mark LogChannel
-
-struct LogInstance {
- LogInstance() : name(), description(), create_callback(nullptr) {}
-
- ConstString name;
- std::string description;
- LogChannelCreateInstance create_callback;
-};
-
-typedef std::vector<LogInstance> LogInstances;
-
-static std::recursive_mutex &GetLogMutex() {
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static LogInstances &GetLogInstances() {
- static LogInstances g_instances;
- return g_instances;
-}
-
-bool PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- LogChannelCreateInstance create_callback) {
- if (create_callback) {
- LogInstance instance;
- assert((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- GetLogInstances().push_back(instance);
- }
- return false;
-}
-
-bool PluginManager::UnregisterPlugin(LogChannelCreateInstance create_callback) {
- if (create_callback) {
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances();
-
- LogInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++pos) {
- if (pos->create_callback == create_callback) {
- instances.erase(pos);
- return true;
- }
- }
- }
- return false;
-}
-
-const char *PluginManager::GetLogChannelCreateNameAtIndex(uint32_t idx) {
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances();
- if (idx < instances.size())
- return instances[idx].name.GetCString();
- return nullptr;
-}
-
-LogChannelCreateInstance
-PluginManager::GetLogChannelCreateCallbackAtIndex(uint32_t idx) {
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
-}
-
-LogChannelCreateInstance
-PluginManager::GetLogChannelCreateCallbackForPluginName(
- const ConstString &name) {
- if (name) {
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances();
-
- LogInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++pos) {
- if (name == pos->name)
- return pos->create_callback;
- }
- }
- return nullptr;
-}
-
#pragma mark Platform
struct PlatformInstance {
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Fri Feb 17 07:27:42 2017
@@ -9,192 +9,36 @@
#include "LogChannelDWARF.h"
-#include "SymbolFileDWARF.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/StreamFile.h"
-#include "lldb/Interpreter/Args.h"
-
using namespace lldb;
using namespace lldb_private;
-// when the one and only logging channel is enabled, then this will be non NULL.
-static LogChannelDWARF *g_log_channel = NULL;
-
-LogChannelDWARF::LogChannelDWARF() : LogChannel() {}
+static constexpr Log::Category g_categories[] = {
+ {{"aranges"},
+ {"log the parsing of .debug_aranges"},
+ DWARF_LOG_DEBUG_ARANGES},
+ {{"comp"},
+ {"log insertions of object files into DWARF debug maps"},
+ DWARF_LOG_TYPE_COMPLETION},
+ {{"info"}, {"log the parsing of .debug_info"}, DWARF_LOG_DEBUG_INFO},
+ {{"line"}, {"log the parsing of .debug_line"}, DWARF_LOG_DEBUG_LINE},
+ {{"lookups"},
+ {"log any lookups that happen by name, regex, or address"},
+ DWARF_LOG_LOOKUPS},
+ {{"map"},
+ {"log struct/unions/class type completions"},
+ DWARF_LOG_DEBUG_MAP},
+ {{"pubnames"},
+ {"log the parsing of .debug_pubnames"},
+ DWARF_LOG_DEBUG_PUBNAMES},
+ {{"pubtypes"},
+ {"log the parsing of .debug_pubtypes"},
+ DWARF_LOG_DEBUG_PUBTYPES},
+};
-LogChannelDWARF::~LogChannelDWARF() {}
+Log::Channel LogChannelDWARF::g_channel(g_categories, DWARF_LOG_DEFAULT);
void LogChannelDWARF::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- LogChannelDWARF::CreateInstance);
-}
-
-void LogChannelDWARF::Terminate() {
- PluginManager::UnregisterPlugin(LogChannelDWARF::CreateInstance);
-}
-
-LogChannel *LogChannelDWARF::CreateInstance() { return new LogChannelDWARF(); }
-
-lldb_private::ConstString LogChannelDWARF::GetPluginNameStatic() {
- return SymbolFileDWARF::GetPluginNameStatic();
-}
-
-const char *LogChannelDWARF::GetPluginDescriptionStatic() {
- return "DWARF log channel for debugging plug-in issues.";
-}
-
-lldb_private::ConstString LogChannelDWARF::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t LogChannelDWARF::GetPluginVersion() { return 1; }
-
-void LogChannelDWARF::Delete() { g_log_channel = NULL; }
-
-void LogChannelDWARF::Disable(const char **categories, Stream *feedback_strm) {
- if (m_log_ap.get() == NULL)
- return;
-
- uint32_t flag_bits = m_log_ap->GetMask().Get();
- for (size_t i = 0; categories[i] != NULL; ++i) {
- const char *arg = categories[i];
-
- if (::strcasecmp(arg, "all") == 0)
- flag_bits &= ~DWARF_LOG_ALL;
- else if (::strcasecmp(arg, "info") == 0)
- flag_bits &= ~DWARF_LOG_DEBUG_INFO;
- else if (::strcasecmp(arg, "line") == 0)
- flag_bits &= ~DWARF_LOG_DEBUG_LINE;
- else if (::strcasecmp(arg, "pubnames") == 0)
- flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
- else if (::strcasecmp(arg, "pubtypes") == 0)
- flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
- else if (::strcasecmp(arg, "aranges") == 0)
- flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
- else if (::strcasecmp(arg, "lookups") == 0)
- flag_bits &= ~DWARF_LOG_LOOKUPS;
- else if (::strcasecmp(arg, "map") == 0)
- flag_bits &= ~DWARF_LOG_DEBUG_MAP;
- else if (::strcasecmp(arg, "default") == 0)
- flag_bits &= ~DWARF_LOG_DEFAULT;
- else if (::strncasecmp(arg, "comp", 4) == 0)
- flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
- else {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListCategories(feedback_strm);
- }
- }
-
- if (flag_bits == 0)
- Delete();
- else
- m_log_ap->GetMask().Reset(flag_bits);
-
- return;
-}
-
-bool LogChannelDWARF::Enable(
- const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options,
- Stream *feedback_strm, // Feedback stream for argument errors etc
- const char **categories // The categories to enable within this logging
- // stream, if empty, enable default set
- ) {
- Delete();
-
- if (m_log_ap)
- m_log_ap->SetStream(log_stream_sp);
- else
- m_log_ap.reset(new Log(log_stream_sp));
-
- g_log_channel = this;
- uint32_t flag_bits = 0;
- bool got_unknown_category = false;
- for (size_t i = 0; categories[i] != NULL; ++i) {
- const char *arg = categories[i];
-
- if (::strcasecmp(arg, "all") == 0)
- flag_bits |= DWARF_LOG_ALL;
- else if (::strcasecmp(arg, "info") == 0)
- flag_bits |= DWARF_LOG_DEBUG_INFO;
- else if (::strcasecmp(arg, "line") == 0)
- flag_bits |= DWARF_LOG_DEBUG_LINE;
- else if (::strcasecmp(arg, "pubnames") == 0)
- flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
- else if (::strcasecmp(arg, "pubtypes") == 0)
- flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
- else if (::strcasecmp(arg, "aranges") == 0)
- flag_bits |= DWARF_LOG_DEBUG_ARANGES;
- else if (::strcasecmp(arg, "lookups") == 0)
- flag_bits |= DWARF_LOG_LOOKUPS;
- else if (::strcasecmp(arg, "map") == 0)
- flag_bits |= DWARF_LOG_DEBUG_MAP;
- else if (::strcasecmp(arg, "default") == 0)
- flag_bits |= DWARF_LOG_DEFAULT;
- else if (::strncasecmp(arg, "comp", 4) == 0)
- flag_bits |= DWARF_LOG_TYPE_COMPLETION;
- else {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- if (got_unknown_category == false) {
- got_unknown_category = true;
- ListCategories(feedback_strm);
- }
- }
- }
- if (flag_bits == 0)
- flag_bits = DWARF_LOG_DEFAULT;
- m_log_ap->GetMask().Reset(flag_bits);
- m_log_ap->GetOptions().Reset(log_options);
- return m_log_ap.get() != NULL;
-}
-
-void LogChannelDWARF::ListCategories(Stream *strm) {
- strm->Printf(
- "Logging categories for '%s':\n"
- " all - turn on all available logging categories\n"
- " info - log the parsing of .debug_info\n"
- " line - log the parsing of .debug_line\n"
- " pubnames - log the parsing of .debug_pubnames\n"
- " pubtypes - log the parsing of .debug_pubtypes\n"
- " aranges - log the parsing of .debug_aranges\n"
- " lookups - log any lookups that happen by name, regex, or address\n"
- " completion - log struct/unions/class type completions\n"
- " map - log insertions of object files into DWARF debug maps\n",
- SymbolFileDWARF::GetPluginNameStatic().GetCString());
-}
-
-Log *LogChannelDWARF::GetLog() {
- if (g_log_channel)
- return g_log_channel->m_log_ap.get();
-
- return NULL;
-}
-
-Log *LogChannelDWARF::GetLogIfAll(uint32_t mask) {
- if (g_log_channel && g_log_channel->m_log_ap.get()) {
- if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
- return g_log_channel->m_log_ap.get();
- }
- return NULL;
+ Log::Register("dwarf", g_channel);
}
-Log *LogChannelDWARF::GetLogIfAny(uint32_t mask) {
- if (g_log_channel && g_log_channel->m_log_ap.get()) {
- if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
- return g_log_channel->m_log_ap.get();
- }
- return NULL;
-}
-
-void LogChannelDWARF::LogIf(uint32_t mask, const char *format, ...) {
- if (g_log_channel) {
- Log *log = g_log_channel->m_log_ap.get();
- if (log && log->GetMask().AnySet(mask)) {
- va_list args;
- va_start(args, format);
- log->VAPrintf(format, args);
- va_end(args);
- }
- }
-}
+void LogChannelDWARF::Terminate() { Log::Unregister("dwarf"); }
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h Fri Feb 17 07:27:42 2017
@@ -27,48 +27,17 @@
#define DWARF_LOG_ALL (UINT32_MAX)
#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
-class LogChannelDWARF : public lldb_private::LogChannel {
-public:
- LogChannelDWARF();
-
- ~LogChannelDWARF() override;
+namespace lldb_private {
+class LogChannelDWARF {
+ static Log::Channel g_channel;
+public:
static void Initialize();
-
static void Terminate();
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- static lldb_private::LogChannel *CreateInstance();
-
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- void Disable(const char **categories,
- lldb_private::Stream *feedback_strm) override;
-
- void Delete();
-
- bool Enable(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options,
- lldb_private::Stream
- *feedback_strm, // Feedback stream for argument errors etc
- const char **categories) override; // The categories to enable
- // within this logging stream,
- // if empty, enable default set
-
- void ListCategories(lldb_private::Stream *strm) override;
-
- static lldb_private::Log *GetLog();
-
- static lldb_private::Log *GetLogIfAll(uint32_t mask);
-
- static lldb_private::Log *GetLogIfAny(uint32_t mask);
-
- static void LogIf(uint32_t mask, const char *format, ...);
+ static Log *GetLogIfAll(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
+ static Log *GetLogIfAny(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
};
+}
#endif // SymbolFileDWARF_LogChannelDWARF_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Feb 17 07:27:42 2017
@@ -223,7 +223,7 @@ void SymbolFileDWARF::DebuggerInitialize
void SymbolFileDWARF::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
- LogChannelDWARF::Initialize();
+ LogChannelDWARF::Terminate();
}
lldb_private::ConstString SymbolFileDWARF::GetPluginNameStatic() {
Modified: lldb/trunk/unittests/Core/LogTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Core/LogTest.cpp?rev=295442&r1=295441&r2=295442&view=diff
==============================================================================
--- lldb/trunk/unittests/Core/LogTest.cpp (original)
+++ lldb/trunk/unittests/Core/LogTest.cpp Fri Feb 17 07:27:42 2017
@@ -12,10 +12,30 @@
#include "lldb/Core/Log.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/Support/ManagedStatic.h"
using namespace lldb;
using namespace lldb_private;
+enum { FOO = 1, BAR = 2 };
+static constexpr Log::Category test_categories[] = {
+ {"foo", "log foo", FOO}, {"bar", "log bar", BAR},
+};
+static constexpr uint32_t default_flags = FOO;
+
+static Log::Channel test_channel(test_categories, default_flags);
+
+struct LogChannelTest : public ::testing::Test {
+ static void SetUpTestCase() {
+ Log::Register("chan", test_channel);
+ }
+
+ static void TearDownTestCase() {
+ Log::Unregister("chan");
+ llvm::llvm_shutdown();
+ }
+};
+
static std::string GetLogString(uint32_t log_options, const char *format,
int arg) {
std::string stream_string;
@@ -57,3 +77,96 @@ TEST(LogTest, log_options) {
GetLogString(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD,
"Hello World {0}", 47));
}
+
+TEST(LogTest, Register) {
+ llvm::llvm_shutdown_obj obj;
+ Log::Register("chan", test_channel);
+ Log::Unregister("chan");
+ Log::Register("chan", test_channel);
+ Log::Unregister("chan");
+}
+
+TEST(LogTest, Unregister) {
+ llvm::llvm_shutdown_obj obj;
+ Log::Register("chan", test_channel);
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
+ const char *cat1[] = {"foo", nullptr};
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ StreamString err;
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat1, err));
+ EXPECT_NE(nullptr, test_channel.GetLogIfAny(FOO));
+ Log::Unregister("chan");
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO));
+}
+
+TEST_F(LogChannelTest, Enable) {
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ StreamString err;
+ EXPECT_FALSE(Log::EnableLogChannel(stream_sp, 0, "chanchan", nullptr, err));
+ EXPECT_EQ("Invalid log channel 'chanchan'.\n", err.GetString());
+ err.Clear();
+
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", nullptr, err));
+ EXPECT_EQ("", err.GetString());
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+
+ const char *cat2[] = {"bar", nullptr};
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat2, err));
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+
+ const char *cat3[] = {"baz", nullptr};
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat3, err));
+ EXPECT_TRUE(err.GetString().contains("unrecognized log category 'baz'"))
+ << "err: " << err.GetString().str();
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+}
+
+TEST_F(LogChannelTest, Disable) {
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(FOO));
+ const char *cat12[] = {"foo", "bar", nullptr};
+ std::string message;
+ std::shared_ptr<llvm::raw_string_ostream> stream_sp(
+ new llvm::raw_string_ostream(message));
+ StreamString err;
+ EXPECT_TRUE(Log::EnableLogChannel(stream_sp, 0, "chan", cat12, err));
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO | BAR));
+
+ const char *cat2[] = {"bar", nullptr};
+ EXPECT_TRUE(Log::DisableLogChannel("chan", cat2, err));
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+
+ const char *cat3[] = {"baz", nullptr};
+ EXPECT_TRUE(Log::DisableLogChannel("chan", cat3, err));
+ EXPECT_TRUE(err.GetString().contains("unrecognized log category 'baz'"))
+ << "err: " << err.GetString().str();
+ EXPECT_NE(nullptr, test_channel.GetLogIfAll(FOO));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAll(BAR));
+ err.Clear();
+
+ EXPECT_TRUE(Log::DisableLogChannel("chan", nullptr, err));
+ EXPECT_EQ(nullptr, test_channel.GetLogIfAny(FOO | BAR));
+}
+
+TEST_F(LogChannelTest, List) {
+ StreamString str;
+ EXPECT_TRUE(Log::ListChannelCategories("chan", str));
+ std::string expected =
+ R"(Logging categories for 'chan':
+ all - all available logging categories
+ default - default set of logging categories
+ foo - log foo
+ bar - log bar
+)";
+ EXPECT_EQ(expected, str.GetString().str());
+ str.Clear();
+
+ EXPECT_FALSE(Log::ListChannelCategories("chanchan", str));
+ EXPECT_EQ("Invalid log channel 'chanchan'.\n", str.GetString().str());
+}
More information about the lldb-commits
mailing list