[Lldb-commits] [lldb] r295201 - Revert "Refactor log channel registration mechanism"
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Feb 15 09:13:20 PST 2017
Author: labath
Date: Wed Feb 15 11:13:19 2017
New Revision: 295201
URL: http://llvm.org/viewvc/llvm-project?rev=295201&view=rev
Log:
Revert "Refactor log channel registration mechanism"
The change breaks on Windows and NetBSD bots. Revert while I
investigate.
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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Log.h (original)
+++ lldb/trunk/include/lldb/Core/Log.h Wed Feb 15 11:13:19 2017
@@ -44,53 +44,6 @@ 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.
//------------------------------------------------------------------
@@ -110,9 +63,6 @@ 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);
@@ -123,13 +73,13 @@ public:
static bool
EnableLogChannel(const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options, llvm::StringRef channel,
+ uint32_t log_options, const char *channel,
const char **categories, Stream &error_stream);
- static bool DisableLogChannel(llvm::StringRef channel,
- const char **categories, Stream &error_stream);
-
- static bool ListChannelCategories(llvm::StringRef channel, Stream &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 void DisableAllLogChannels(Stream *feedback_strm);
@@ -140,6 +90,12 @@ public:
static void Terminate();
//------------------------------------------------------------------
+ // Auto completion
+ //------------------------------------------------------------------
+ static void AutoCompleteChannelName(const char *channel_name,
+ StringList &matches);
+
+ //------------------------------------------------------------------
// Member functions
//------------------------------------------------------------------
Log();
@@ -206,6 +162,34 @@ 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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/PluginManager.h (original)
+++ lldb/trunk/include/lldb/Core/PluginManager.h Wed Feb 15 11:13:19 2017
@@ -210,6 +210,22 @@ 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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Wed Feb 15 11:13:19 2017
@@ -127,6 +127,7 @@ class MemoryRegionInfo;
class LineTable;
class Listener;
class Log;
+class LogChannel;
class Mangled;
class Materializer;
class MemoryHistory;
@@ -361,6 +362,7 @@ 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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-private-interfaces.h (original)
+++ lldb/trunk/include/lldb/lldb-private-interfaces.h Wed Feb 15 11:13:19 2017
@@ -45,6 +45,7 @@ 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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectLog.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectLog.cpp Wed Feb 15 11:13:19 2017
@@ -227,15 +227,25 @@ protected:
return false;
}
+ Log::Callbacks log_callbacks;
+
const std::string channel = args[0].ref;
args.Shift(); // Shift off the channel
- if (channel == "all") {
- Log::DisableAllLogChannels(&result.GetErrorStream());
+ if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
+ log_callbacks.disable(args.GetConstArgumentVector(),
+ &result.GetErrorStream());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else if (channel == "all") {
+ Log::DisableAllLogChannels(&result.GetErrorStream());
} else {
- if (Log::DisableLogChannel(channel, args.GetConstArgumentVector(),
- result.GetErrorStream()))
+ LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel.data()));
+ if (log_channel_sp) {
+ log_channel_sp->Disable(args.GetConstArgumentVector(),
+ &result.GetErrorStream());
result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ } else
+ result.AppendErrorWithFormat("Invalid log channel '%s'.\n",
+ channel.data());
}
return result.Succeeded();
}
@@ -274,12 +284,26 @@ protected:
Log::ListAllLogChannels(&result.GetOutputStream());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
- bool success = true;
- for (const auto &entry : args.entries())
- success = success && Log::ListChannelCategories(
- entry.ref, result.GetOutputStream());
- if (success)
- result.SetStatus(eReturnStatusSuccessFinishResult);
+ 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());
+ }
+ }
}
return result.Succeeded();
}
Modified: lldb/trunk/source/Core/Log.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Log.cpp?rev=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/source/Core/Log.cpp (original)
+++ lldb/trunk/source/Core/Log.cpp Wed Feb 15 11:13:19 2017
@@ -18,10 +18,8 @@
#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"
@@ -38,76 +36,6 @@
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)
@@ -224,6 +152,9 @@ 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() {
@@ -231,17 +162,9 @@ static CallbackMap &GetCallbackMap() {
return g_callback_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);
+static LogChannelMap &GetChannelMap() {
+ static LogChannelMap g_channel_map;
+ return g_channel_map;
}
void Log::RegisterLogChannel(const ConstString &channel,
@@ -267,7 +190,7 @@ bool Log::GetLogChannelCallbacks(const C
bool Log::EnableLogChannel(
const std::shared_ptr<llvm::raw_ostream> &log_stream_sp,
- uint32_t log_options, llvm::StringRef channel, const char **categories,
+ uint32_t log_options, const char *channel, const char **categories,
Stream &error_stream) {
Log::Callbacks log_callbacks;
if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
@@ -275,52 +198,52 @@ bool Log::EnableLogChannel(
return true;
}
- auto iter = g_channel_map->find(channel);
- if (iter == g_channel_map->end()) {
- error_stream.Format("Invalid log channel '{0}'.\n", channel);
+ 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);
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;
}
-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;
- }
+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();
- auto iter = g_channel_map->find(channel);
- if (iter == g_channel_map->end()) {
- error_stream.Format("Invalid log channel '{0}'.\n", channel);
- return false;
+ for (pos = callback_map.begin(); pos != end; ++pos)
+ pos->second.enable(log_stream_sp, log_options, 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->Enable(log_stream_sp, log_options, feedback_strm,
+ categories);
}
- uint32_t flags = categories && categories[0]
- ? GetFlags(error_stream, *iter, categories)
- : UINT32_MAX;
- iter->second.channel.Disable(flags);
- return true;
}
-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;
+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);
}
-
- 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) {
@@ -331,8 +254,11 @@ void Log::DisableAllLogChannels(Stream *
for (pos = callback_map.begin(); pos != end; ++pos)
pos->second.disable(categories, feedback_strm);
- for (auto &entry : *g_channel_map)
- entry.second.channel.Disable(UINT32_MAX);
+ 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);
}
void Log::Initialize() {
@@ -344,8 +270,9 @@ void Log::Terminate() { DisableAllLogCha
void Log::ListAllLogChannels(Stream *strm) {
CallbackMap &callback_map = GetCallbackMap();
+ LogChannelMap &channel_map = GetChannelMap();
- if (callback_map.empty() && g_channel_map->empty()) {
+ if (callback_map.empty() && channel_map.empty()) {
strm->PutCString("No logging channels are currently registered.\n");
return;
}
@@ -354,9 +281,17 @@ void Log::ListAllLogChannels(Stream *str
for (pos = callback_map.begin(); pos != end; ++pos)
pos->second.list_categories(strm);
- for (const auto &channel : *g_channel_map)
- ListCategories(*strm, channel);
+ 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);
+ }
}
+
bool Log::GetVerbose() const { return m_options.Test(LLDB_LOG_OPTION_VERBOSE); }
void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
@@ -423,3 +358,33 @@ 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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/source/Core/PluginManager.cpp (original)
+++ lldb/trunk/source/Core/PluginManager.cpp Wed Feb 15 11:13:19 2017
@@ -1167,6 +1167,93 @@ 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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Wed Feb 15 11:13:19 2017
@@ -9,28 +9,192 @@
#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;
-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},
-};
+// when the one and only logging channel is enabled, then this will be non NULL.
+static LogChannelDWARF *g_log_channel = NULL;
+
+LogChannelDWARF::LogChannelDWARF() : LogChannel() {}
-Log::Channel LogChannelDWARF::g_channel(g_categories, DWARF_LOG_DEFAULT);
+LogChannelDWARF::~LogChannelDWARF() {}
void LogChannelDWARF::Initialize() {
- Log::Register("dwarf", g_channel);
+ 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;
}
-void LogChannelDWARF::Terminate() { Log::Unregister("dwarf"); }
+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);
+ }
+ }
+}
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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h Wed Feb 15 11:13:19 2017
@@ -27,17 +27,48 @@
#define DWARF_LOG_ALL (UINT32_MAX)
#define DWARF_LOG_DEFAULT (DWARF_LOG_DEBUG_INFO)
-namespace lldb_private {
-class LogChannelDWARF {
- static Log::Channel g_channel;
-
+class LogChannelDWARF : public lldb_private::LogChannel {
public:
+ LogChannelDWARF();
+
+ ~LogChannelDWARF() override;
+
static void Initialize();
+
static void Terminate();
- static Log *GetLogIfAll(uint32_t mask) { return g_channel.GetLogIfAll(mask); }
- static Log *GetLogIfAny(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
+ 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, ...);
};
-}
#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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Feb 15 11:13:19 2017
@@ -223,7 +223,7 @@ void SymbolFileDWARF::DebuggerInitialize
void SymbolFileDWARF::Terminate() {
PluginManager::UnregisterPlugin(CreateInstance);
- LogChannelDWARF::Terminate();
+ LogChannelDWARF::Initialize();
}
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=295201&r1=295200&r2=295201&view=diff
==============================================================================
--- lldb/trunk/unittests/Core/LogTest.cpp (original)
+++ lldb/trunk/unittests/Core/LogTest.cpp Wed Feb 15 11:13:19 2017
@@ -12,30 +12,10 @@
#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;
@@ -77,96 +57,3 @@ 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