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