• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Log()37 Log::Log () :
38     m_stream_sp(),
39     m_options(0),
40     m_mask_bits(0)
41 {
42 }
43 
Log(const StreamSP & stream_sp)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 
~Log()51 Log::~Log ()
52 {
53 }
54 
55 Flags &
GetOptions()56 Log::GetOptions()
57 {
58     return m_options;
59 }
60 
61 const Flags &
GetOptions() const62 Log::GetOptions() const
63 {
64     return m_options;
65 }
66 
67 Flags &
GetMask()68 Log::GetMask()
69 {
70     return m_mask_bits;
71 }
72 
73 const Flags &
GetMask() const74 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
PrintfWithFlagsVarArg(uint32_t flags,const char * format,va_list args)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
PutCString(const char * cstr)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
Printf(const char * format,...)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
VAPrintf(const char * format,va_list args)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
PrintfWithFlags(uint32_t flags,const char * format,...)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
Debug(const char * format,...)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
DebugVerbose(const char * format,...)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
LogIf(uint32_t bits,const char * format,...)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
Error(const char * format,...)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
FatalError(int err,const char * format,...)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
Verbose(const char * format,...)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
WarningVerbose(const char * format,...)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
Warning(const char * format,...)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 &
GetCallbackMap()326 GetCallbackMap ()
327 {
328     static CallbackMap g_callback_map;
329     return g_callback_map;
330 }
331 
332 static LogChannelMap &
GetChannelMap()333 GetChannelMap ()
334 {
335     static LogChannelMap g_channel_map;
336     return g_channel_map;
337 }
338 
339 void
RegisterLogChannel(const ConstString & channel,const Log::Callbacks & log_callbacks)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
UnregisterLogChannel(const ConstString & channel)346 Log::UnregisterLogChannel (const ConstString &channel)
347 {
348     return GetCallbackMap().erase(channel) != 0;
349 }
350 
351 bool
GetLogChannelCallbacks(const ConstString & channel,Log::Callbacks & log_callbacks)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
EnableAllLogChannels(StreamSP & log_stream_sp,uint32_t log_options,const char ** categories,Stream * feedback_strm)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
AutoCompleteChannelName(const char * channel_name,StringList & matches)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
DisableAllLogChannels(Stream * feedback_strm)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
Initialize()427 Log::Initialize()
428 {
429     Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
430     Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
431 }
432 
433 void
Terminate()434 Log::Terminate ()
435 {
436     DisableAllLogChannels (NULL);
437 }
438 
439 void
ListAllLogChannels(Stream * strm)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
GetVerbose() const466 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
GetDebug() const481 Log::GetDebug() const
482 {
483     if (m_stream_sp)
484         return m_stream_sp->GetDebug();
485     return false;
486 }
487 
488 
489 LogChannelSP
FindPlugin(const char * plugin_name)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 
LogChannel()520 LogChannel::LogChannel () :
521     m_log_ap ()
522 {
523 }
524 
~LogChannel()525 LogChannel::~LogChannel ()
526 {
527 }
528 
529 
530