Home | History | Annotate | Download | only in DWARF
      1 //===-- LogChannelDWARF.cpp ------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "LogChannelDWARF.h"
     11 
     12 #include "lldb/Interpreter/Args.h"
     13 #include "lldb/Core/PluginManager.h"
     14 #include "lldb/Core/StreamFile.h"
     15 #include "SymbolFileDWARF.h"
     16 
     17 using namespace lldb;
     18 using namespace lldb_private;
     19 
     20 
     21 // when the one and only logging channel is abled, then this will be non NULL.
     22 static LogChannelDWARF* g_log_channel = NULL;
     23 
     24 LogChannelDWARF::LogChannelDWARF () :
     25     LogChannel ()
     26 {
     27 }
     28 
     29 LogChannelDWARF::~LogChannelDWARF ()
     30 {
     31 }
     32 
     33 
     34 void
     35 LogChannelDWARF::Initialize()
     36 {
     37     PluginManager::RegisterPlugin (GetPluginNameStatic(),
     38                                    GetPluginDescriptionStatic(),
     39                                    LogChannelDWARF::CreateInstance);
     40 }
     41 
     42 void
     43 LogChannelDWARF::Terminate()
     44 {
     45     PluginManager::UnregisterPlugin (LogChannelDWARF::CreateInstance);
     46 }
     47 
     48 LogChannel*
     49 LogChannelDWARF::CreateInstance ()
     50 {
     51     return new LogChannelDWARF ();
     52 }
     53 
     54 lldb_private::ConstString
     55 LogChannelDWARF::GetPluginNameStatic()
     56 {
     57     return SymbolFileDWARF::GetPluginNameStatic();
     58 }
     59 
     60 const char *
     61 LogChannelDWARF::GetPluginDescriptionStatic()
     62 {
     63     return "DWARF log channel for debugging plug-in issues.";
     64 }
     65 
     66 lldb_private::ConstString
     67 LogChannelDWARF::GetPluginName()
     68 {
     69     return GetPluginNameStatic();
     70 }
     71 
     72 uint32_t
     73 LogChannelDWARF::GetPluginVersion()
     74 {
     75     return 1;
     76 }
     77 
     78 
     79 void
     80 LogChannelDWARF::Delete ()
     81 {
     82     g_log_channel = NULL;
     83 }
     84 
     85 
     86 void
     87 LogChannelDWARF::Disable (const char **categories, Stream *feedback_strm)
     88 {
     89     if (m_log_ap.get() == NULL)
     90         return;
     91 
     92     uint32_t flag_bits = m_log_ap->GetMask().Get();
     93     for (size_t i = 0; categories[i] != NULL; ++i)
     94     {
     95          const char *arg = categories[i];
     96 
     97         if      (::strcasecmp (arg, "all")        == 0) flag_bits &= ~DWARF_LOG_ALL;
     98         else if (::strcasecmp (arg, "info")       == 0) flag_bits &= ~DWARF_LOG_DEBUG_INFO;
     99         else if (::strcasecmp (arg, "line")       == 0) flag_bits &= ~DWARF_LOG_DEBUG_LINE;
    100         else if (::strcasecmp (arg, "pubnames")   == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBNAMES;
    101         else if (::strcasecmp (arg, "pubtypes")   == 0) flag_bits &= ~DWARF_LOG_DEBUG_PUBTYPES;
    102         else if (::strcasecmp (arg, "aranges")    == 0) flag_bits &= ~DWARF_LOG_DEBUG_ARANGES;
    103         else if (::strcasecmp (arg, "lookups")    == 0) flag_bits &= ~DWARF_LOG_LOOKUPS;
    104         else if (::strcasecmp (arg, "map")        == 0) flag_bits &= ~DWARF_LOG_DEBUG_MAP;
    105         else if (::strcasecmp (arg, "default")    == 0) flag_bits &= ~DWARF_LOG_DEFAULT;
    106         else if (::strncasecmp(arg, "comp", 4)    == 0) flag_bits &= ~DWARF_LOG_TYPE_COMPLETION;
    107         else
    108         {
    109             feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
    110             ListCategories (feedback_strm);
    111         }
    112    }
    113 
    114     if (flag_bits == 0)
    115         Delete ();
    116     else
    117         m_log_ap->GetMask().Reset (flag_bits);
    118 
    119     return;
    120 }
    121 
    122 bool
    123 LogChannelDWARF::Enable
    124 (
    125     StreamSP &log_stream_sp,
    126     uint32_t log_options,
    127     Stream *feedback_strm,  // Feedback stream for argument errors etc
    128     const char **categories  // The categories to enable within this logging stream, if empty, enable default set
    129 )
    130 {
    131     Delete ();
    132 
    133     if (m_log_ap)
    134         m_log_ap->SetStream(log_stream_sp);
    135     else
    136         m_log_ap.reset(new Log (log_stream_sp));
    137 
    138     g_log_channel = this;
    139     uint32_t flag_bits = 0;
    140     bool got_unknown_category = false;
    141     for (size_t i = 0; categories[i] != NULL; ++i)
    142     {
    143         const char *arg = categories[i];
    144 
    145         if      (::strcasecmp (arg, "all")        == 0) flag_bits |= DWARF_LOG_ALL;
    146         else if (::strcasecmp (arg, "info")       == 0) flag_bits |= DWARF_LOG_DEBUG_INFO;
    147         else if (::strcasecmp (arg, "line")       == 0) flag_bits |= DWARF_LOG_DEBUG_LINE;
    148         else if (::strcasecmp (arg, "pubnames")   == 0) flag_bits |= DWARF_LOG_DEBUG_PUBNAMES;
    149         else if (::strcasecmp (arg, "pubtypes")   == 0) flag_bits |= DWARF_LOG_DEBUG_PUBTYPES;
    150         else if (::strcasecmp (arg, "aranges")    == 0) flag_bits |= DWARF_LOG_DEBUG_ARANGES;
    151         else if (::strcasecmp (arg, "lookups")    == 0) flag_bits |= DWARF_LOG_LOOKUPS;
    152         else if (::strcasecmp (arg, "map")        == 0) flag_bits |= DWARF_LOG_DEBUG_MAP;
    153         else if (::strcasecmp (arg, "default")    == 0) flag_bits |= DWARF_LOG_DEFAULT;
    154         else if (::strncasecmp(arg, "comp", 4)    == 0) flag_bits |= DWARF_LOG_TYPE_COMPLETION;
    155         else
    156         {
    157             feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
    158             if (got_unknown_category == false)
    159             {
    160                 got_unknown_category = true;
    161                 ListCategories (feedback_strm);
    162             }
    163         }
    164     }
    165     if (flag_bits == 0)
    166         flag_bits = DWARF_LOG_DEFAULT;
    167     m_log_ap->GetMask().Reset(flag_bits);
    168     m_log_ap->GetOptions().Reset(log_options);
    169     return m_log_ap.get() != NULL;
    170 }
    171 
    172 void
    173 LogChannelDWARF::ListCategories (Stream *strm)
    174 {
    175     strm->Printf ("Logging categories for '%s':\n"
    176                   "  all - turn on all available logging categories\n"
    177                   "  info - log the parsing if .debug_info\n"
    178                   "  line - log the parsing if .debug_line\n"
    179                   "  pubnames - log the parsing if .debug_pubnames\n"
    180                   "  pubtypes - log the parsing if .debug_pubtypes\n"
    181                   "  lookups - log any lookups that happen by name, regex, or address\n"
    182                   "  completion - log struct/unions/class type completions\n"
    183                   "  map - log insertions of object files into DWARF debug maps\n",
    184                   SymbolFileDWARF::GetPluginNameStatic().GetCString());
    185 }
    186 
    187 Log *
    188 LogChannelDWARF::GetLog ()
    189 {
    190     if (g_log_channel)
    191         return g_log_channel->m_log_ap.get();
    192 
    193     return NULL;
    194 }
    195 
    196 Log *
    197 LogChannelDWARF::GetLogIfAll (uint32_t mask)
    198 {
    199     if (g_log_channel && g_log_channel->m_log_ap.get())
    200     {
    201         if (g_log_channel->m_log_ap->GetMask().AllSet(mask))
    202             return g_log_channel->m_log_ap.get();
    203     }
    204     return NULL;
    205 }
    206 
    207 Log *
    208 LogChannelDWARF::GetLogIfAny (uint32_t mask)
    209 {
    210     if (g_log_channel && g_log_channel->m_log_ap.get())
    211     {
    212         if (g_log_channel->m_log_ap->GetMask().AnySet(mask))
    213             return g_log_channel->m_log_ap.get();
    214     }
    215     return NULL;
    216 }
    217 
    218 void
    219 LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...)
    220 {
    221     if (g_log_channel)
    222     {
    223         Log *log = g_log_channel->m_log_ap.get();
    224         if (log && log->GetMask().AnySet(mask))
    225         {
    226             va_list args;
    227             va_start (args, format);
    228             log->VAPrintf (format, args);
    229             va_end (args);
    230         }
    231     }
    232 }
    233