diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp')
| -rw-r--r-- | source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp new file mode 100644 index 000000000000..27fa261813bb --- /dev/null +++ b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp @@ -0,0 +1,232 @@ +//===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LogChannelDWARF.h" + +#include "lldb/Interpreter/Args.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamFile.h" +#include "SymbolFileDWARF.h" + +using namespace lldb; +using namespace lldb_private; + + +// when the one and only logging channel is abled, then this will be non NULL. +static LogChannelDWARF* g_log_channel = NULL; + +LogChannelDWARF::LogChannelDWARF () : + LogChannel () +{ +} + +LogChannelDWARF::~LogChannelDWARF () +{ +} + + +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 +( + StreamSP &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 if .debug_info\n" + " line - log the parsing if .debug_line\n" + " pubnames - log the parsing if .debug_pubnames\n" + " pubtypes - log the parsing if .debug_pubtypes\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 * +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); + } + } +} |
