blob: 3743631fbb78823a37f8414b4ed6813ab37ed13d [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// C Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#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"
Caroline Tice20ad3c42010-10-29 21:48:37 +000033#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034using namespace lldb;
35using namespace lldb_private;
36
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037Log::Log () :
38 m_stream_sp(),
39 m_options(0),
40 m_mask_bits(0)
41{
42}
43
44Log::Log (StreamSP &stream_sp) :
45 m_stream_sp(stream_sp),
46 m_options(0),
47 m_mask_bits(0)
48{
49}
50
51Log::~Log ()
52{
53}
54
55Flags &
56Log::GetOptions()
57{
58 return m_options;
59}
60
61const Flags &
62Log::GetOptions() const
63{
64 return m_options;
65}
66
67Flags &
68Log::GetMask()
69{
70 return m_mask_bits;
71}
72
73const Flags &
74Log::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//----------------------------------------------------------------------
85void
86Log::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;
Greg Clayton64195a22011-02-23 00:35:02 +000092 // 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);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096
97 // Add a sequence ID if requested
Greg Clayton73b472d2010-10-27 03:32:59 +000098 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 header.Printf ("%u ", ++g_sequence_id);
100
101 // Timestamp if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000102 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 {
104 struct timeval tv = TimeValue::Now().GetAsTimeVal();
Daniel Maleaa85e6b62012-12-07 22:21:08 +0000105 header.Printf ("%9ld.%6.6d ", tv.tv_sec, (int32_t)tv.tv_usec);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106 }
107
108 // Add the process and thread if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000109 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
Daniel Malead01b2952012-11-29 21:49:15 +0000110 header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111
112 // Add the process and thread if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000113 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114 {
Greg Clayton85719632013-02-27 22:51:58 +0000115 std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID()));
116 if (!thread_name.empty())
117 header.Printf ("%s ", thread_name.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118 }
119
120 header.PrintfVarArg (format, args);
121 m_stream_sp->Printf("%s\n", header.GetData());
Greg Clayton3a18e312012-10-08 22:41:53 +0000122
123 if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE))
124 Host::Backtrace (*m_stream_sp, 1024);
Jim Ingham228063c2012-02-21 02:23:08 +0000125 m_stream_sp->Flush();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 }
127}
128
129
130void
131Log::PutCString (const char *cstr)
132{
133 Printf ("%s", cstr);
134}
135
136
137//----------------------------------------------------------------------
138// Simple variable argument logging with flags.
139//----------------------------------------------------------------------
140void
141Log::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
149void
150Log::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//----------------------------------------------------------------------
159void
160Log::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//----------------------------------------------------------------------
172void
173Log::Debug (const char *format, ...)
174{
Greg Clayton73b472d2010-10-27 03:32:59 +0000175 if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176 {
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//----------------------------------------------------------------------
189void
190Log::DebugVerbose (const char *format, ...)
191{
Greg Clayton73b472d2010-10-27 03:32:59 +0000192 if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193 {
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//----------------------------------------------------------------------
205void
206Log::LogIf (uint32_t bits, const char *format, ...)
207{
Greg Clayton73b472d2010-10-27 03:32:59 +0000208 if (m_options.AllSet (bits))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209 {
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//----------------------------------------------------------------------
221void
222Log::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//----------------------------------------------------------------------
241void
242Log::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//----------------------------------------------------------------------
263void
264Log::Verbose (const char *format, ...)
265{
Greg Clayton73b472d2010-10-27 03:32:59 +0000266 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267 {
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//----------------------------------------------------------------------
279void
280Log::WarningVerbose (const char *format, ...)
281{
Greg Clayton73b472d2010-10-27 03:32:59 +0000282 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 {
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//----------------------------------------------------------------------
300void
301Log::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
316typedef std::map <std::string, Log::Callbacks> CallbackMap;
317typedef CallbackMap::iterator CallbackMapIter;
318
319typedef std::map <ConstString, LogChannelSP> LogChannelMap;
320typedef LogChannelMap::iterator LogChannelMapIter;
321
322
323// Surround our callback map with a singleton function so we don't have any
324// global initializers.
325static CallbackMap &
326GetCallbackMap ()
327{
328 static CallbackMap g_callback_map;
329 return g_callback_map;
330}
331
332static LogChannelMap &
333GetChannelMap ()
334{
335 static LogChannelMap g_channel_map;
336 return g_channel_map;
337}
338
339void
340Log::RegisterLogChannel (const char *channel, const Log::Callbacks &log_callbacks)
341{
342 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
343}
344
345bool
346Log::UnregisterLogChannel (const char *channel)
347{
348 return GetCallbackMap().erase(channel) != 0;
349}
350
351bool
352Log::GetLogChannelCallbacks (const char *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 }
Greg Clayton72b77eb2011-02-04 21:13:05 +0000361 ::memset (&log_callbacks, 0, sizeof(log_callbacks));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362 return false;
363}
364
365void
366Log::EnableAllLogChannels
367(
368 StreamSP &log_stream_sp,
369 uint32_t log_options,
Jim Ingham228063c2012-02-21 02:23:08 +0000370 const char **categories,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371 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)
Jim Ingham228063c2012-02-21 02:23:08 +0000378 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379
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 {
Jim Ingham228063c2012-02-21 02:23:08 +0000384 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 }
386
387}
388
389void
Greg Claytonab65b342011-04-13 22:47:15 +0000390Log::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
410void
Caroline Tice20ad3c42010-10-29 21:48:37 +0000411Log::DisableAllLogChannels (Stream *feedback_strm)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412{
413 CallbackMap &callback_map = GetCallbackMap ();
414 CallbackMapIter pos, end = callback_map.end();
Jim Ingham228063c2012-02-21 02:23:08 +0000415 const char *categories[1] = {NULL};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416
417 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000418 pos->second.disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419
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)
Jim Ingham228063c2012-02-21 02:23:08 +0000423 channel_pos->second->Disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424}
425
426void
Greg Clayton99d0faf2010-11-18 23:32:35 +0000427Log::Initialize()
428{
429 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
430 Log::RegisterLogChannel ("lldb", log_callbacks);
431}
432
433void
434Log::Terminate ()
435{
436 DisableAllLogChannels (NULL);
437}
438
439void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440Log::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
465bool
466Log::GetVerbose() const
467{
Jim Inghamd8d148e2011-01-22 01:24:30 +0000468 // 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 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//------------------------------------------------------------------
480bool
481Log::GetDebug() const
482{
483 if (m_stream_sp)
484 return m_stream_sp->GetDebug();
485 return false;
486}
487
488
489LogChannelSP
490LogChannel::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 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (plugin_name);
499 if (create_callback)
500 {
501 log_channel_sp.reset(create_callback());
502 if (log_channel_sp)
503 {
504 // Cache the one and only loaded instance of each log channel
505 // plug-in after it has been loaded once.
506 channel_map[log_channel_name] = log_channel_sp;
507 }
508 }
509 }
510 else
511 {
512 // We have already loaded an instance of this log channel class,
513 // so just return the cached instance.
514 log_channel_sp = pos->second;
515 }
516 return log_channel_sp;
517}
518
519LogChannel::LogChannel () :
520 m_log_sp ()
521{
522}
523
524LogChannel::~LogChannel ()
525{
526}
527
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528