blob: b8671f7ddc9a2956857d402abc3d836169b5d429 [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
10// C Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include <pthread.h>
12#include <stdio.h>
13#include <stdarg.h>
14#include <stdlib.h>
15#include <unistd.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"
Caroline Tice20ad3c42010-10-29 21:48:37 +000031#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032using namespace lldb;
33using namespace lldb_private;
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035Log::Log () :
36 m_stream_sp(),
37 m_options(0),
38 m_mask_bits(0)
39{
40}
41
42Log::Log (StreamSP &stream_sp) :
43 m_stream_sp(stream_sp),
44 m_options(0),
45 m_mask_bits(0)
46{
47}
48
49Log::~Log ()
50{
51}
52
53Flags &
54Log::GetOptions()
55{
56 return m_options;
57}
58
59const Flags &
60Log::GetOptions() const
61{
62 return m_options;
63}
64
65Flags &
66Log::GetMask()
67{
68 return m_mask_bits;
69}
70
71const Flags &
72Log::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//----------------------------------------------------------------------
83void
84Log::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;
Greg Clayton64195a22011-02-23 00:35:02 +000090 // 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);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094
95 // Add a sequence ID if requested
Greg Clayton73b472d2010-10-27 03:32:59 +000096 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097 header.Printf ("%u ", ++g_sequence_id);
98
99 // Timestamp if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000100 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 {
102 struct timeval tv = TimeValue::Now().GetAsTimeVal();
Daniel Malead01b2952012-11-29 21:49:15 +0000103 header.Printf ("%9ld.%6.6ld ", tv.tv_sec, tv.tv_usec);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 }
105
106 // Add the process and thread if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000107 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
Daniel Malead01b2952012-11-29 21:49:15 +0000108 header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109
110 // Add the process and thread if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000111 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 {
Eli Friedmane01b70b2010-06-11 04:29:29 +0000113 const char *thread_name_str = Host::GetThreadName (getpid(), Host::GetCurrentThreadID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114 if (thread_name_str)
115 header.Printf ("%s ", thread_name_str);
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000116
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117 }
118
119 header.PrintfVarArg (format, args);
120 m_stream_sp->Printf("%s\n", header.GetData());
Greg Clayton3a18e312012-10-08 22:41:53 +0000121
122 if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE))
123 Host::Backtrace (*m_stream_sp, 1024);
Jim Ingham228063c2012-02-21 02:23:08 +0000124 m_stream_sp->Flush();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125 }
126}
127
128
129void
130Log::PutCString (const char *cstr)
131{
132 Printf ("%s", cstr);
133}
134
135
136//----------------------------------------------------------------------
137// Simple variable argument logging with flags.
138//----------------------------------------------------------------------
139void
140Log::Printf(const char *format, ...)
141{
142 va_list args;
143 va_start (args, format);
144 PrintfWithFlagsVarArg (0, format, args);
145 va_end (args);
146}
147
148void
149Log::VAPrintf (const char *format, va_list args)
150{
151 PrintfWithFlagsVarArg (0, format, args);
152}
153
154
155//----------------------------------------------------------------------
156// Simple variable argument logging with flags.
157//----------------------------------------------------------------------
158void
159Log::PrintfWithFlags (uint32_t flags, const char *format, ...)
160{
161 va_list args;
162 va_start (args, format);
163 PrintfWithFlagsVarArg (flags, format, args);
164 va_end (args);
165}
166
167//----------------------------------------------------------------------
168// Print debug strings if and only if the global debug option is set to
169// a non-zero value.
170//----------------------------------------------------------------------
171void
172Log::Debug (const char *format, ...)
173{
Greg Clayton73b472d2010-10-27 03:32:59 +0000174 if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175 {
176 va_list args;
177 va_start (args, format);
178 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args);
179 va_end (args);
180 }
181}
182
183
184//----------------------------------------------------------------------
185// Print debug strings if and only if the global debug option is set to
186// a non-zero value.
187//----------------------------------------------------------------------
188void
189Log::DebugVerbose (const char *format, ...)
190{
Greg Clayton73b472d2010-10-27 03:32:59 +0000191 if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192 {
193 va_list args;
194 va_start (args, format);
195 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args);
196 va_end (args);
197 }
198}
199
200
201//----------------------------------------------------------------------
202// Log only if all of the bits are set
203//----------------------------------------------------------------------
204void
205Log::LogIf (uint32_t bits, const char *format, ...)
206{
Greg Clayton73b472d2010-10-27 03:32:59 +0000207 if (m_options.AllSet (bits))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208 {
209 va_list args;
210 va_start (args, format);
211 PrintfWithFlagsVarArg (0, format, args);
212 va_end (args);
213 }
214}
215
216
217//----------------------------------------------------------------------
218// Printing of errors that are not fatal.
219//----------------------------------------------------------------------
220void
221Log::Error (const char *format, ...)
222{
223 char *arg_msg = NULL;
224 va_list args;
225 va_start (args, format);
226 ::vasprintf (&arg_msg, format, args);
227 va_end (args);
228
229 if (arg_msg != NULL)
230 {
231 PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg);
232 free (arg_msg);
233 }
234}
235
236//----------------------------------------------------------------------
237// Printing of errors that ARE fatal. Exit with ERR exit code
238// immediately.
239//----------------------------------------------------------------------
240void
241Log::FatalError (int err, const char *format, ...)
242{
243 char *arg_msg = NULL;
244 va_list args;
245 va_start (args, format);
246 ::vasprintf (&arg_msg, format, args);
247 va_end (args);
248
249 if (arg_msg != NULL)
250 {
251 PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg);
252 ::free (arg_msg);
253 }
254 ::exit (err);
255}
256
257
258//----------------------------------------------------------------------
259// Printing of warnings that are not fatal only if verbose mode is
260// enabled.
261//----------------------------------------------------------------------
262void
263Log::Verbose (const char *format, ...)
264{
Greg Clayton73b472d2010-10-27 03:32:59 +0000265 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266 {
267 va_list args;
268 va_start (args, format);
269 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args);
270 va_end (args);
271 }
272}
273
274//----------------------------------------------------------------------
275// Printing of warnings that are not fatal only if verbose mode is
276// enabled.
277//----------------------------------------------------------------------
278void
279Log::WarningVerbose (const char *format, ...)
280{
Greg Clayton73b472d2010-10-27 03:32:59 +0000281 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282 {
283 char *arg_msg = NULL;
284 va_list args;
285 va_start (args, format);
286 ::vasprintf (&arg_msg, format, args);
287 va_end (args);
288
289 if (arg_msg != NULL)
290 {
291 PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg);
292 free (arg_msg);
293 }
294 }
295}
296//----------------------------------------------------------------------
297// Printing of warnings that are not fatal.
298//----------------------------------------------------------------------
299void
300Log::Warning (const char *format, ...)
301{
302 char *arg_msg = NULL;
303 va_list args;
304 va_start (args, format);
305 ::vasprintf (&arg_msg, format, args);
306 va_end (args);
307
308 if (arg_msg != NULL)
309 {
310 PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg);
311 free (arg_msg);
312 }
313}
314
315typedef std::map <std::string, Log::Callbacks> CallbackMap;
316typedef CallbackMap::iterator CallbackMapIter;
317
318typedef std::map <ConstString, LogChannelSP> LogChannelMap;
319typedef LogChannelMap::iterator LogChannelMapIter;
320
321
322// Surround our callback map with a singleton function so we don't have any
323// global initializers.
324static CallbackMap &
325GetCallbackMap ()
326{
327 static CallbackMap g_callback_map;
328 return g_callback_map;
329}
330
331static LogChannelMap &
332GetChannelMap ()
333{
334 static LogChannelMap g_channel_map;
335 return g_channel_map;
336}
337
338void
339Log::RegisterLogChannel (const char *channel, const Log::Callbacks &log_callbacks)
340{
341 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
342}
343
344bool
345Log::UnregisterLogChannel (const char *channel)
346{
347 return GetCallbackMap().erase(channel) != 0;
348}
349
350bool
351Log::GetLogChannelCallbacks (const char *channel, Log::Callbacks &log_callbacks)
352{
353 CallbackMap &callback_map = GetCallbackMap ();
354 CallbackMapIter pos = callback_map.find(channel);
355 if (pos != callback_map.end())
356 {
357 log_callbacks = pos->second;
358 return true;
359 }
Greg Clayton72b77eb2011-02-04 21:13:05 +0000360 ::memset (&log_callbacks, 0, sizeof(log_callbacks));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 return false;
362}
363
364void
365Log::EnableAllLogChannels
366(
367 StreamSP &log_stream_sp,
368 uint32_t log_options,
Jim Ingham228063c2012-02-21 02:23:08 +0000369 const char **categories,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370 Stream *feedback_strm
371)
372{
373 CallbackMap &callback_map = GetCallbackMap ();
374 CallbackMapIter pos, end = callback_map.end();
375
376 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000377 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378
379 LogChannelMap &channel_map = GetChannelMap ();
380 LogChannelMapIter channel_pos, channel_end = channel_map.end();
381 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
382 {
Jim Ingham228063c2012-02-21 02:23:08 +0000383 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384 }
385
386}
387
388void
Greg Claytonab65b342011-04-13 22:47:15 +0000389Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
390{
391 LogChannelMap &map = GetChannelMap ();
392 LogChannelMapIter pos, end = map.end();
393 for (pos = map.begin(); pos != end; ++pos)
394 {
395 const char *pos_channel_name = pos->first.GetCString();
396 if (channel_name && channel_name[0])
397 {
398 if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
399 {
400 matches.AppendString(pos_channel_name);
401 }
402 }
403 else
404 matches.AppendString(pos_channel_name);
405
406 }
407}
408
409void
Caroline Tice20ad3c42010-10-29 21:48:37 +0000410Log::DisableAllLogChannels (Stream *feedback_strm)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411{
412 CallbackMap &callback_map = GetCallbackMap ();
413 CallbackMapIter pos, end = callback_map.end();
Jim Ingham228063c2012-02-21 02:23:08 +0000414 const char *categories[1] = {NULL};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000415
416 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000417 pos->second.disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418
419 LogChannelMap &channel_map = GetChannelMap ();
420 LogChannelMapIter channel_pos, channel_end = channel_map.end();
421 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000422 channel_pos->second->Disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423}
424
425void
Greg Clayton99d0faf2010-11-18 23:32:35 +0000426Log::Initialize()
427{
428 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
429 Log::RegisterLogChannel ("lldb", log_callbacks);
430}
431
432void
433Log::Terminate ()
434{
435 DisableAllLogChannels (NULL);
436}
437
438void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439Log::ListAllLogChannels (Stream *strm)
440{
441 CallbackMap &callback_map = GetCallbackMap ();
442 LogChannelMap &channel_map = GetChannelMap ();
443
444 if (callback_map.empty() && channel_map.empty())
445 {
446 strm->PutCString ("No logging channels are currently registered.\n");
447 return;
448 }
449
450 CallbackMapIter pos, end = callback_map.end();
451 for (pos = callback_map.begin(); pos != end; ++pos)
452 pos->second.list_categories (strm);
453
454 uint32_t idx = 0;
455 const char *name;
456 for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
457 {
458 LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
459 if (log_channel_sp)
460 log_channel_sp->ListCategories (strm);
461 }
462}
463
464bool
465Log::GetVerbose() const
466{
Jim Inghamd8d148e2011-01-22 01:24:30 +0000467 // FIXME: This has to be centralized between the stream and the log...
468 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
469 return true;
470
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471 if (m_stream_sp)
472 return m_stream_sp->GetVerbose();
473 return false;
474}
475
476//------------------------------------------------------------------
477// Returns true if the debug flag bit is set in this stream.
478//------------------------------------------------------------------
479bool
480Log::GetDebug() const
481{
482 if (m_stream_sp)
483 return m_stream_sp->GetDebug();
484 return false;
485}
486
487
488LogChannelSP
489LogChannel::FindPlugin (const char *plugin_name)
490{
491 LogChannelSP log_channel_sp;
492 LogChannelMap &channel_map = GetChannelMap ();
493 ConstString log_channel_name (plugin_name);
494 LogChannelMapIter pos = channel_map.find (log_channel_name);
495 if (pos == channel_map.end())
496 {
497 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (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
518LogChannel::LogChannel () :
519 m_log_sp ()
520{
521}
522
523LogChannel::~LogChannel ()
524{
525}
526
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000527