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