blob: d205d363b764f897bb11b8eb00b3624a79962201 [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 <stdio.h>
14#include <stdarg.h>
15#include <stdlib.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016
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"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Host/Mutex.h"
Zachary Turner39de3112014-09-09 20:54:56 +000030#include "lldb/Host/ThisThread.h"
31#include "lldb/Host/TimeValue.h"
Caroline Tice20ad3c42010-10-29 21:48:37 +000032#include "lldb/Interpreter/Args.h"
Zachary Turner39de3112014-09-09 20:54:56 +000033
34#include "llvm/ADT/SmallString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035using namespace lldb;
36using namespace lldb_private;
37
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038Log::Log () :
39 m_stream_sp(),
40 m_options(0),
41 m_mask_bits(0)
42{
43}
44
Greg Clayton5160ce52013-03-27 23:08:40 +000045Log::Log (const StreamSP &stream_sp) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 m_stream_sp(stream_sp),
47 m_options(0),
48 m_mask_bits(0)
49{
50}
51
52Log::~Log ()
53{
54}
55
56Flags &
57Log::GetOptions()
58{
59 return m_options;
60}
61
62const Flags &
63Log::GetOptions() const
64{
65 return m_options;
66}
67
68Flags &
69Log::GetMask()
70{
71 return m_mask_bits;
72}
73
74const Flags &
75Log::GetMask() const
76{
77 return m_mask_bits;
78}
79
80
81//----------------------------------------------------------------------
82// All logging eventually boils down to this function call. If we have
83// a callback registered, then we call the logging callback. If we have
84// a valid file handle, we also log to the file.
85//----------------------------------------------------------------------
86void
87Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args)
88{
Greg Claytone98008c2014-02-13 23:34:38 +000089 // Make a copy of our stream shared pointer in case someone disables our
90 // log while we are logging and releases the stream
91 StreamSP stream_sp(m_stream_sp);
92 if (stream_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 {
94 static uint32_t g_sequence_id = 0;
95 StreamString header;
Greg Clayton64195a22011-02-23 00:35:02 +000096 // Enabling the thread safe logging actually deadlocks right now.
97 // Need to fix this at some point.
98// static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);
99// Mutex::Locker locker (g_LogThreadedMutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100
101 // Add a sequence ID if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000102 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 header.Printf ("%u ", ++g_sequence_id);
104
105 // Timestamp if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000106 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107 {
Virgile Bello0a3b1512013-09-04 13:56:11 +0000108 TimeValue now = TimeValue::Now();
Jason Molenda3c2daca2013-09-11 21:00:37 +0000109 header.Printf ("%9d.%6.6d ", now.seconds(), now.nanoseconds());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 }
111
112 // Add the process and thread if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000113 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
Daniel Malead01b2952012-11-29 21:49:15 +0000114 header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115
Ed Mastecc913d142014-05-21 13:46:46 +0000116 // Add the thread name if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000117 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118 {
Zachary Turner39de3112014-09-09 20:54:56 +0000119 llvm::SmallString<32> thread_name;
120 ThisThread::GetName(thread_name);
Greg Clayton85719632013-02-27 22:51:58 +0000121 if (!thread_name.empty())
122 header.Printf ("%s ", thread_name.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123 }
124
125 header.PrintfVarArg (format, args);
Greg Claytone98008c2014-02-13 23:34:38 +0000126 stream_sp->Printf("%s\n", header.GetData());
Greg Clayton3a18e312012-10-08 22:41:53 +0000127
128 if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE))
Greg Claytone98008c2014-02-13 23:34:38 +0000129 Host::Backtrace (*stream_sp, 1024);
130 stream_sp->Flush();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131 }
132}
133
134
135void
136Log::PutCString (const char *cstr)
137{
138 Printf ("%s", cstr);
139}
140
141
142//----------------------------------------------------------------------
143// Simple variable argument logging with flags.
144//----------------------------------------------------------------------
145void
146Log::Printf(const char *format, ...)
147{
148 va_list args;
149 va_start (args, format);
150 PrintfWithFlagsVarArg (0, format, args);
151 va_end (args);
152}
153
154void
155Log::VAPrintf (const char *format, va_list args)
156{
157 PrintfWithFlagsVarArg (0, format, args);
158}
159
160
161//----------------------------------------------------------------------
162// Simple variable argument logging with flags.
163//----------------------------------------------------------------------
164void
165Log::PrintfWithFlags (uint32_t flags, const char *format, ...)
166{
167 va_list args;
168 va_start (args, format);
169 PrintfWithFlagsVarArg (flags, format, args);
170 va_end (args);
171}
172
173//----------------------------------------------------------------------
174// Print debug strings if and only if the global debug option is set to
175// a non-zero value.
176//----------------------------------------------------------------------
177void
178Log::Debug (const char *format, ...)
179{
Greg Clayton73b472d2010-10-27 03:32:59 +0000180 if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 {
182 va_list args;
183 va_start (args, format);
184 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args);
185 va_end (args);
186 }
187}
188
189
190//----------------------------------------------------------------------
191// Print debug strings if and only if the global debug option is set to
192// a non-zero value.
193//----------------------------------------------------------------------
194void
195Log::DebugVerbose (const char *format, ...)
196{
Greg Clayton73b472d2010-10-27 03:32:59 +0000197 if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198 {
199 va_list args;
200 va_start (args, format);
201 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args);
202 va_end (args);
203 }
204}
205
206
207//----------------------------------------------------------------------
208// Log only if all of the bits are set
209//----------------------------------------------------------------------
210void
211Log::LogIf (uint32_t bits, const char *format, ...)
212{
Greg Clayton73b472d2010-10-27 03:32:59 +0000213 if (m_options.AllSet (bits))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214 {
215 va_list args;
216 va_start (args, format);
217 PrintfWithFlagsVarArg (0, format, args);
218 va_end (args);
219 }
220}
221
222
223//----------------------------------------------------------------------
224// Printing of errors that are not fatal.
225//----------------------------------------------------------------------
226void
227Log::Error (const char *format, ...)
228{
229 char *arg_msg = NULL;
230 va_list args;
231 va_start (args, format);
232 ::vasprintf (&arg_msg, format, args);
233 va_end (args);
234
235 if (arg_msg != NULL)
236 {
237 PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg);
238 free (arg_msg);
239 }
240}
241
242//----------------------------------------------------------------------
243// Printing of errors that ARE fatal. Exit with ERR exit code
244// immediately.
245//----------------------------------------------------------------------
246void
247Log::FatalError (int err, const char *format, ...)
248{
249 char *arg_msg = NULL;
250 va_list args;
251 va_start (args, format);
252 ::vasprintf (&arg_msg, format, args);
253 va_end (args);
254
255 if (arg_msg != NULL)
256 {
257 PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg);
258 ::free (arg_msg);
259 }
260 ::exit (err);
261}
262
263
264//----------------------------------------------------------------------
265// Printing of warnings that are not fatal only if verbose mode is
266// enabled.
267//----------------------------------------------------------------------
268void
269Log::Verbose (const char *format, ...)
270{
Greg Clayton73b472d2010-10-27 03:32:59 +0000271 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000272 {
273 va_list args;
274 va_start (args, format);
275 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args);
276 va_end (args);
277 }
278}
279
280//----------------------------------------------------------------------
281// Printing of warnings that are not fatal only if verbose mode is
282// enabled.
283//----------------------------------------------------------------------
284void
285Log::WarningVerbose (const char *format, ...)
286{
Greg Clayton73b472d2010-10-27 03:32:59 +0000287 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288 {
289 char *arg_msg = NULL;
290 va_list args;
291 va_start (args, format);
292 ::vasprintf (&arg_msg, format, args);
293 va_end (args);
294
295 if (arg_msg != NULL)
296 {
297 PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg);
298 free (arg_msg);
299 }
300 }
301}
302//----------------------------------------------------------------------
303// Printing of warnings that are not fatal.
304//----------------------------------------------------------------------
305void
306Log::Warning (const char *format, ...)
307{
308 char *arg_msg = NULL;
309 va_list args;
310 va_start (args, format);
311 ::vasprintf (&arg_msg, format, args);
312 va_end (args);
313
314 if (arg_msg != NULL)
315 {
316 PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg);
317 free (arg_msg);
318 }
319}
320
Greg Clayton57abc5d2013-05-10 21:47:16 +0000321typedef std::map <ConstString, Log::Callbacks> CallbackMap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322typedef CallbackMap::iterator CallbackMapIter;
323
324typedef std::map <ConstString, LogChannelSP> LogChannelMap;
325typedef LogChannelMap::iterator LogChannelMapIter;
326
327
328// Surround our callback map with a singleton function so we don't have any
329// global initializers.
330static CallbackMap &
331GetCallbackMap ()
332{
333 static CallbackMap g_callback_map;
334 return g_callback_map;
335}
336
337static LogChannelMap &
338GetChannelMap ()
339{
340 static LogChannelMap g_channel_map;
341 return g_channel_map;
342}
343
344void
Greg Clayton57abc5d2013-05-10 21:47:16 +0000345Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346{
347 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
348}
349
350bool
Greg Clayton57abc5d2013-05-10 21:47:16 +0000351Log::UnregisterLogChannel (const ConstString &channel)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352{
353 return GetCallbackMap().erase(channel) != 0;
354}
355
356bool
Greg Clayton57abc5d2013-05-10 21:47:16 +0000357Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358{
359 CallbackMap &callback_map = GetCallbackMap ();
360 CallbackMapIter pos = callback_map.find(channel);
361 if (pos != callback_map.end())
362 {
363 log_callbacks = pos->second;
364 return true;
365 }
Greg Clayton72b77eb2011-02-04 21:13:05 +0000366 ::memset (&log_callbacks, 0, sizeof(log_callbacks));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367 return false;
368}
369
370void
371Log::EnableAllLogChannels
372(
373 StreamSP &log_stream_sp,
374 uint32_t log_options,
Jim Ingham228063c2012-02-21 02:23:08 +0000375 const char **categories,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 Stream *feedback_strm
377)
378{
379 CallbackMap &callback_map = GetCallbackMap ();
380 CallbackMapIter pos, end = callback_map.end();
381
382 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000383 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384
385 LogChannelMap &channel_map = GetChannelMap ();
386 LogChannelMapIter channel_pos, channel_end = channel_map.end();
387 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
388 {
Jim Ingham228063c2012-02-21 02:23:08 +0000389 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 }
391
392}
393
394void
Greg Claytonab65b342011-04-13 22:47:15 +0000395Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
396{
397 LogChannelMap &map = GetChannelMap ();
398 LogChannelMapIter pos, end = map.end();
399 for (pos = map.begin(); pos != end; ++pos)
400 {
401 const char *pos_channel_name = pos->first.GetCString();
402 if (channel_name && channel_name[0])
403 {
404 if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
405 {
406 matches.AppendString(pos_channel_name);
407 }
408 }
409 else
410 matches.AppendString(pos_channel_name);
411
412 }
413}
414
415void
Caroline Tice20ad3c42010-10-29 21:48:37 +0000416Log::DisableAllLogChannels (Stream *feedback_strm)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417{
418 CallbackMap &callback_map = GetCallbackMap ();
419 CallbackMapIter pos, end = callback_map.end();
Jim Ingham228063c2012-02-21 02:23:08 +0000420 const char *categories[1] = {NULL};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421
422 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000423 pos->second.disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424
425 LogChannelMap &channel_map = GetChannelMap ();
426 LogChannelMapIter channel_pos, channel_end = channel_map.end();
427 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000428 channel_pos->second->Disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429}
430
431void
Greg Clayton99d0faf2010-11-18 23:32:35 +0000432Log::Initialize()
433{
434 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
Greg Clayton57abc5d2013-05-10 21:47:16 +0000435 Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
Greg Clayton99d0faf2010-11-18 23:32:35 +0000436}
437
438void
439Log::Terminate ()
440{
441 DisableAllLogChannels (NULL);
442}
443
444void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445Log::ListAllLogChannels (Stream *strm)
446{
447 CallbackMap &callback_map = GetCallbackMap ();
448 LogChannelMap &channel_map = GetChannelMap ();
449
450 if (callback_map.empty() && channel_map.empty())
451 {
452 strm->PutCString ("No logging channels are currently registered.\n");
453 return;
454 }
455
456 CallbackMapIter pos, end = callback_map.end();
457 for (pos = callback_map.begin(); pos != end; ++pos)
458 pos->second.list_categories (strm);
459
460 uint32_t idx = 0;
461 const char *name;
462 for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
463 {
464 LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
465 if (log_channel_sp)
466 log_channel_sp->ListCategories (strm);
467 }
468}
469
470bool
471Log::GetVerbose() const
472{
Jim Inghamd8d148e2011-01-22 01:24:30 +0000473 // FIXME: This has to be centralized between the stream and the log...
474 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
475 return true;
476
Greg Claytone98008c2014-02-13 23:34:38 +0000477 // Make a copy of our stream shared pointer in case someone disables our
478 // log while we are logging and releases the stream
479 StreamSP stream_sp(m_stream_sp);
480 if (stream_sp)
481 return stream_sp->GetVerbose();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482 return false;
483}
484
485//------------------------------------------------------------------
486// Returns true if the debug flag bit is set in this stream.
487//------------------------------------------------------------------
488bool
489Log::GetDebug() const
490{
Greg Claytone98008c2014-02-13 23:34:38 +0000491 // Make a copy of our stream shared pointer in case someone disables our
492 // log while we are logging and releases the stream
493 StreamSP stream_sp(m_stream_sp);
494 if (stream_sp)
495 return stream_sp->GetDebug();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 return false;
497}
498
499
500LogChannelSP
501LogChannel::FindPlugin (const char *plugin_name)
502{
503 LogChannelSP log_channel_sp;
504 LogChannelMap &channel_map = GetChannelMap ();
505 ConstString log_channel_name (plugin_name);
506 LogChannelMapIter pos = channel_map.find (log_channel_name);
507 if (pos == channel_map.end())
508 {
Greg Clayton57abc5d2013-05-10 21:47:16 +0000509 ConstString const_plugin_name (plugin_name);
510 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511 if (create_callback)
512 {
513 log_channel_sp.reset(create_callback());
514 if (log_channel_sp)
515 {
516 // Cache the one and only loaded instance of each log channel
517 // plug-in after it has been loaded once.
518 channel_map[log_channel_name] = log_channel_sp;
519 }
520 }
521 }
522 else
523 {
524 // We have already loaded an instance of this log channel class,
525 // so just return the cached instance.
526 log_channel_sp = pos->second;
527 }
528 return log_channel_sp;
529}
530
531LogChannel::LogChannel () :
Greg Clayton5160ce52013-03-27 23:08:40 +0000532 m_log_ap ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533{
534}
535
536LogChannel::~LogChannel ()
537{
538}
539
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540