Home | History | Annotate | Download | only in Core
      1 //===-- Log.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 "lldb/lldb-python.h"
     11 
     12 // C Includes
     13 #include <pthread.h>
     14 #include <stdio.h>
     15 #include <stdarg.h>
     16 #include <stdlib.h>
     17 #include <unistd.h>
     18 
     19 // C++ Includes
     20 #include <map>
     21 #include <string>
     22 
     23 // Other libraries and framework includes
     24 // Project includes
     25 #include "lldb/Core/Debugger.h"
     26 #include "lldb/Core/Log.h"
     27 #include "lldb/Core/PluginManager.h"
     28 #include "lldb/Core/StreamFile.h"
     29 #include "lldb/Core/StreamString.h"
     30 #include "lldb/Host/Host.h"
     31 #include "lldb/Host/TimeValue.h"
     32 #include "lldb/Host/Mutex.h"
     33 #include "lldb/Interpreter/Args.h"
     34 using namespace lldb;
     35 using namespace lldb_private;
     36 
     37 Log::Log () :
     38     m_stream_sp(),
     39     m_options(0),
     40     m_mask_bits(0)
     41 {
     42 }
     43 
     44 Log::Log (const StreamSP &stream_sp) :
     45     m_stream_sp(stream_sp),
     46     m_options(0),
     47     m_mask_bits(0)
     48 {
     49 }
     50 
     51 Log::~Log ()
     52 {
     53 }
     54 
     55 Flags &
     56 Log::GetOptions()
     57 {
     58     return m_options;
     59 }
     60 
     61 const Flags &
     62 Log::GetOptions() const
     63 {
     64     return m_options;
     65 }
     66 
     67 Flags &
     68 Log::GetMask()
     69 {
     70     return m_mask_bits;
     71 }
     72 
     73 const Flags &
     74 Log::GetMask() const
     75 {
     76     return m_mask_bits;
     77 }
     78 
     79 
     80 //----------------------------------------------------------------------
     81 // All logging eventually boils down to this function call. If we have
     82 // a callback registered, then we call the logging callback. If we have
     83 // a valid file handle, we also log to the file.
     84 //----------------------------------------------------------------------
     85 void
     86 Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args)
     87 {
     88     if (m_stream_sp)
     89     {
     90         static uint32_t g_sequence_id = 0;
     91         StreamString header;
     92 		// Enabling the thread safe logging actually deadlocks right now.
     93 		// Need to fix this at some point.
     94 //        static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);
     95 //        Mutex::Locker locker (g_LogThreadedMutex);
     96 
     97         // Add a sequence ID if requested
     98         if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
     99             header.Printf ("%u ", ++g_sequence_id);
    100 
    101         // Timestamp if requested
    102         if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
    103         {
    104             struct timeval tv = TimeValue::Now().GetAsTimeVal();
    105             header.Printf ("%9ld.%6.6d ", tv.tv_sec, (int32_t)tv.tv_usec);
    106         }
    107 
    108         // Add the process and thread if requested
    109         if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
    110             header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
    111 
    112         // Add the process and thread if requested
    113         if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
    114         {
    115             std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID()));
    116             if (!thread_name.empty())
    117                 header.Printf ("%s ", thread_name.c_str());
    118         }
    119 
    120         header.PrintfVarArg (format, args);
    121         m_stream_sp->Printf("%s\n", header.GetData());
    122 
    123         if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE))
    124             Host::Backtrace (*m_stream_sp, 1024);
    125         m_stream_sp->Flush();
    126     }
    127 }
    128 
    129 
    130 void
    131 Log::PutCString (const char *cstr)
    132 {
    133     Printf ("%s", cstr);
    134 }
    135 
    136 
    137 //----------------------------------------------------------------------
    138 // Simple variable argument logging with flags.
    139 //----------------------------------------------------------------------
    140 void
    141 Log::Printf(const char *format, ...)
    142 {
    143     va_list args;
    144     va_start (args, format);
    145     PrintfWithFlagsVarArg (0, format, args);
    146     va_end (args);
    147 }
    148 
    149 void
    150 Log::VAPrintf (const char *format, va_list args)
    151 {
    152     PrintfWithFlagsVarArg (0, format, args);
    153 }
    154 
    155 
    156 //----------------------------------------------------------------------
    157 // Simple variable argument logging with flags.
    158 //----------------------------------------------------------------------
    159 void
    160 Log::PrintfWithFlags (uint32_t flags, const char *format, ...)
    161 {
    162     va_list args;
    163     va_start (args, format);
    164     PrintfWithFlagsVarArg (flags, format, args);
    165     va_end (args);
    166 }
    167 
    168 //----------------------------------------------------------------------
    169 // Print debug strings if and only if the global debug option is set to
    170 // a non-zero value.
    171 //----------------------------------------------------------------------
    172 void
    173 Log::Debug (const char *format, ...)
    174 {
    175     if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
    176     {
    177         va_list args;
    178         va_start (args, format);
    179         PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args);
    180         va_end (args);
    181     }
    182 }
    183 
    184 
    185 //----------------------------------------------------------------------
    186 // Print debug strings if and only if the global debug option is set to
    187 // a non-zero value.
    188 //----------------------------------------------------------------------
    189 void
    190 Log::DebugVerbose (const char *format, ...)
    191 {
    192     if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
    193     {
    194         va_list args;
    195         va_start (args, format);
    196         PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args);
    197         va_end (args);
    198     }
    199 }
    200 
    201 
    202 //----------------------------------------------------------------------
    203 // Log only if all of the bits are set
    204 //----------------------------------------------------------------------
    205 void
    206 Log::LogIf (uint32_t bits, const char *format, ...)
    207 {
    208     if (m_options.AllSet (bits))
    209     {
    210         va_list args;
    211         va_start (args, format);
    212         PrintfWithFlagsVarArg (0, format, args);
    213         va_end (args);
    214     }
    215 }
    216 
    217 
    218 //----------------------------------------------------------------------
    219 // Printing of errors that are not fatal.
    220 //----------------------------------------------------------------------
    221 void
    222 Log::Error (const char *format, ...)
    223 {
    224     char *arg_msg = NULL;
    225     va_list args;
    226     va_start (args, format);
    227     ::vasprintf (&arg_msg, format, args);
    228     va_end (args);
    229 
    230     if (arg_msg != NULL)
    231     {
    232         PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg);
    233         free (arg_msg);
    234     }
    235 }
    236 
    237 //----------------------------------------------------------------------
    238 // Printing of errors that ARE fatal. Exit with ERR exit code
    239 // immediately.
    240 //----------------------------------------------------------------------
    241 void
    242 Log::FatalError (int err, const char *format, ...)
    243 {
    244     char *arg_msg = NULL;
    245     va_list args;
    246     va_start (args, format);
    247     ::vasprintf (&arg_msg, format, args);
    248     va_end (args);
    249 
    250     if (arg_msg != NULL)
    251     {
    252         PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg);
    253         ::free (arg_msg);
    254     }
    255     ::exit (err);
    256 }
    257 
    258 
    259 //----------------------------------------------------------------------
    260 // Printing of warnings that are not fatal only if verbose mode is
    261 // enabled.
    262 //----------------------------------------------------------------------
    263 void
    264 Log::Verbose (const char *format, ...)
    265 {
    266     if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
    267     {
    268         va_list args;
    269         va_start (args, format);
    270         PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args);
    271         va_end (args);
    272     }
    273 }
    274 
    275 //----------------------------------------------------------------------
    276 // Printing of warnings that are not fatal only if verbose mode is
    277 // enabled.
    278 //----------------------------------------------------------------------
    279 void
    280 Log::WarningVerbose (const char *format, ...)
    281 {
    282     if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
    283     {
    284         char *arg_msg = NULL;
    285         va_list args;
    286         va_start (args, format);
    287         ::vasprintf (&arg_msg, format, args);
    288         va_end (args);
    289 
    290         if (arg_msg != NULL)
    291         {
    292             PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg);
    293             free (arg_msg);
    294         }
    295     }
    296 }
    297 //----------------------------------------------------------------------
    298 // Printing of warnings that are not fatal.
    299 //----------------------------------------------------------------------
    300 void
    301 Log::Warning (const char *format, ...)
    302 {
    303     char *arg_msg = NULL;
    304     va_list args;
    305     va_start (args, format);
    306     ::vasprintf (&arg_msg, format, args);
    307     va_end (args);
    308 
    309     if (arg_msg != NULL)
    310     {
    311         PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg);
    312         free (arg_msg);
    313     }
    314 }
    315 
    316 typedef std::map <ConstString, Log::Callbacks> CallbackMap;
    317 typedef CallbackMap::iterator CallbackMapIter;
    318 
    319 typedef std::map <ConstString, LogChannelSP> LogChannelMap;
    320 typedef LogChannelMap::iterator LogChannelMapIter;
    321 
    322 
    323 // Surround our callback map with a singleton function so we don't have any
    324 // global initializers.
    325 static CallbackMap &
    326 GetCallbackMap ()
    327 {
    328     static CallbackMap g_callback_map;
    329     return g_callback_map;
    330 }
    331 
    332 static LogChannelMap &
    333 GetChannelMap ()
    334 {
    335     static LogChannelMap g_channel_map;
    336     return g_channel_map;
    337 }
    338 
    339 void
    340 Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
    341 {
    342     GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
    343 }
    344 
    345 bool
    346 Log::UnregisterLogChannel (const ConstString &channel)
    347 {
    348     return GetCallbackMap().erase(channel) != 0;
    349 }
    350 
    351 bool
    352 Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
    353 {
    354     CallbackMap &callback_map = GetCallbackMap ();
    355     CallbackMapIter pos = callback_map.find(channel);
    356     if (pos != callback_map.end())
    357     {
    358         log_callbacks = pos->second;
    359         return true;
    360     }
    361     ::memset (&log_callbacks, 0, sizeof(log_callbacks));
    362     return false;
    363 }
    364 
    365 void
    366 Log::EnableAllLogChannels
    367 (
    368     StreamSP &log_stream_sp,
    369     uint32_t log_options,
    370     const char **categories,
    371     Stream *feedback_strm
    372 )
    373 {
    374     CallbackMap &callback_map = GetCallbackMap ();
    375     CallbackMapIter pos, end = callback_map.end();
    376 
    377     for (pos = callback_map.begin(); pos != end; ++pos)
    378         pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
    379 
    380     LogChannelMap &channel_map = GetChannelMap ();
    381     LogChannelMapIter channel_pos, channel_end = channel_map.end();
    382     for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
    383     {
    384         channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
    385     }
    386 
    387 }
    388 
    389 void
    390 Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
    391 {
    392     LogChannelMap &map = GetChannelMap ();
    393     LogChannelMapIter pos, end = map.end();
    394     for (pos = map.begin(); pos != end; ++pos)
    395     {
    396         const char *pos_channel_name = pos->first.GetCString();
    397         if (channel_name && channel_name[0])
    398         {
    399             if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
    400             {
    401                 matches.AppendString(pos_channel_name);
    402             }
    403         }
    404         else
    405             matches.AppendString(pos_channel_name);
    406 
    407     }
    408 }
    409 
    410 void
    411 Log::DisableAllLogChannels (Stream *feedback_strm)
    412 {
    413     CallbackMap &callback_map = GetCallbackMap ();
    414     CallbackMapIter pos, end = callback_map.end();
    415     const char *categories[1] = {NULL};
    416 
    417     for (pos = callback_map.begin(); pos != end; ++pos)
    418         pos->second.disable (categories, feedback_strm);
    419 
    420     LogChannelMap &channel_map = GetChannelMap ();
    421     LogChannelMapIter channel_pos, channel_end = channel_map.end();
    422     for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
    423         channel_pos->second->Disable (categories, feedback_strm);
    424 }
    425 
    426 void
    427 Log::Initialize()
    428 {
    429     Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
    430     Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
    431 }
    432 
    433 void
    434 Log::Terminate ()
    435 {
    436     DisableAllLogChannels (NULL);
    437 }
    438 
    439 void
    440 Log::ListAllLogChannels (Stream *strm)
    441 {
    442     CallbackMap &callback_map = GetCallbackMap ();
    443     LogChannelMap &channel_map = GetChannelMap ();
    444 
    445     if (callback_map.empty() && channel_map.empty())
    446     {
    447         strm->PutCString ("No logging channels are currently registered.\n");
    448         return;
    449     }
    450 
    451     CallbackMapIter pos, end = callback_map.end();
    452     for (pos = callback_map.begin(); pos != end; ++pos)
    453         pos->second.list_categories (strm);
    454 
    455     uint32_t idx = 0;
    456     const char *name;
    457     for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
    458     {
    459         LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
    460         if (log_channel_sp)
    461             log_channel_sp->ListCategories (strm);
    462     }
    463 }
    464 
    465 bool
    466 Log::GetVerbose() const
    467 {
    468     // FIXME: This has to be centralized between the stream and the log...
    469     if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
    470         return true;
    471 
    472     if (m_stream_sp)
    473         return m_stream_sp->GetVerbose();
    474     return false;
    475 }
    476 
    477 //------------------------------------------------------------------
    478 // Returns true if the debug flag bit is set in this stream.
    479 //------------------------------------------------------------------
    480 bool
    481 Log::GetDebug() const
    482 {
    483     if (m_stream_sp)
    484         return m_stream_sp->GetDebug();
    485     return false;
    486 }
    487 
    488 
    489 LogChannelSP
    490 LogChannel::FindPlugin (const char *plugin_name)
    491 {
    492     LogChannelSP log_channel_sp;
    493     LogChannelMap &channel_map = GetChannelMap ();
    494     ConstString log_channel_name (plugin_name);
    495     LogChannelMapIter pos = channel_map.find (log_channel_name);
    496     if (pos == channel_map.end())
    497     {
    498         ConstString const_plugin_name (plugin_name);
    499         LogChannelCreateInstance create_callback  = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
    500         if (create_callback)
    501         {
    502             log_channel_sp.reset(create_callback());
    503             if (log_channel_sp)
    504             {
    505                 // Cache the one and only loaded instance of each log channel
    506                 // plug-in after it has been loaded once.
    507                 channel_map[log_channel_name] = log_channel_sp;
    508             }
    509         }
    510     }
    511     else
    512     {
    513         // We have already loaded an instance of this log channel class,
    514         // so just return the cached instance.
    515         log_channel_sp = pos->second;
    516     }
    517     return log_channel_sp;
    518 }
    519 
    520 LogChannel::LogChannel () :
    521     m_log_ap ()
    522 {
    523 }
    524 
    525 LogChannel::~LogChannel ()
    526 {
    527 }
    528 
    529 
    530