1 //===-- Log.cpp -------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
23 // Other libraries and framework 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"
33 #include "lldb/Interpreter/Args.h"
35 using namespace lldb_private;
44 Log::Log (const StreamSP &stream_sp) :
45 m_stream_sp(stream_sp),
62 Log::GetOptions() const
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 //----------------------------------------------------------------------
86 Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args)
90 static uint32_t g_sequence_id = 0;
92 // 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);
97 // Add a sequence ID if requested
98 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
99 header.Printf ("%u ", ++g_sequence_id);
101 // Timestamp if requested
102 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
104 struct timeval tv = TimeValue::Now().GetAsTimeVal();
105 header.Printf ("%9ld.%6.6d ", tv.tv_sec, (int32_t)tv.tv_usec);
108 // Add the process and thread if requested
109 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
110 header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
112 // Add the process and thread if requested
113 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
115 std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID()));
116 if (!thread_name.empty())
117 header.Printf ("%s ", thread_name.c_str());
120 header.PrintfVarArg (format, args);
121 m_stream_sp->Printf("%s\n", header.GetData());
123 if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE))
124 Host::Backtrace (*m_stream_sp, 1024);
125 m_stream_sp->Flush();
131 Log::PutCString (const char *cstr)
137 //----------------------------------------------------------------------
138 // Simple variable argument logging with flags.
139 //----------------------------------------------------------------------
141 Log::Printf(const char *format, ...)
144 va_start (args, format);
145 PrintfWithFlagsVarArg (0, format, args);
150 Log::VAPrintf (const char *format, va_list args)
152 PrintfWithFlagsVarArg (0, format, args);
156 //----------------------------------------------------------------------
157 // Simple variable argument logging with flags.
158 //----------------------------------------------------------------------
160 Log::PrintfWithFlags (uint32_t flags, const char *format, ...)
163 va_start (args, format);
164 PrintfWithFlagsVarArg (flags, format, args);
168 //----------------------------------------------------------------------
169 // Print debug strings if and only if the global debug option is set to
171 //----------------------------------------------------------------------
173 Log::Debug (const char *format, ...)
175 if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
178 va_start (args, format);
179 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args);
185 //----------------------------------------------------------------------
186 // Print debug strings if and only if the global debug option is set to
188 //----------------------------------------------------------------------
190 Log::DebugVerbose (const char *format, ...)
192 if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
195 va_start (args, format);
196 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args);
202 //----------------------------------------------------------------------
203 // Log only if all of the bits are set
204 //----------------------------------------------------------------------
206 Log::LogIf (uint32_t bits, const char *format, ...)
208 if (m_options.AllSet (bits))
211 va_start (args, format);
212 PrintfWithFlagsVarArg (0, format, args);
218 //----------------------------------------------------------------------
219 // Printing of errors that are not fatal.
220 //----------------------------------------------------------------------
222 Log::Error (const char *format, ...)
224 char *arg_msg = NULL;
226 va_start (args, format);
227 ::vasprintf (&arg_msg, format, args);
232 PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg);
237 //----------------------------------------------------------------------
238 // Printing of errors that ARE fatal. Exit with ERR exit code
240 //----------------------------------------------------------------------
242 Log::FatalError (int err, const char *format, ...)
244 char *arg_msg = NULL;
246 va_start (args, format);
247 ::vasprintf (&arg_msg, format, args);
252 PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg);
259 //----------------------------------------------------------------------
260 // Printing of warnings that are not fatal only if verbose mode is
262 //----------------------------------------------------------------------
264 Log::Verbose (const char *format, ...)
266 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
269 va_start (args, format);
270 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args);
275 //----------------------------------------------------------------------
276 // Printing of warnings that are not fatal only if verbose mode is
278 //----------------------------------------------------------------------
280 Log::WarningVerbose (const char *format, ...)
282 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
284 char *arg_msg = NULL;
286 va_start (args, format);
287 ::vasprintf (&arg_msg, format, args);
292 PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg);
297 //----------------------------------------------------------------------
298 // Printing of warnings that are not fatal.
299 //----------------------------------------------------------------------
301 Log::Warning (const char *format, ...)
303 char *arg_msg = NULL;
305 va_start (args, format);
306 ::vasprintf (&arg_msg, format, args);
311 PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg);
316 typedef std::map <ConstString, Log::Callbacks> CallbackMap;
317 typedef CallbackMap::iterator CallbackMapIter;
319 typedef std::map <ConstString, LogChannelSP> LogChannelMap;
320 typedef LogChannelMap::iterator LogChannelMapIter;
323 // Surround our callback map with a singleton function so we don't have any
324 // global initializers.
328 static CallbackMap g_callback_map;
329 return g_callback_map;
332 static LogChannelMap &
335 static LogChannelMap g_channel_map;
336 return g_channel_map;
340 Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
342 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
346 Log::UnregisterLogChannel (const ConstString &channel)
348 return GetCallbackMap().erase(channel) != 0;
352 Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
354 CallbackMap &callback_map = GetCallbackMap ();
355 CallbackMapIter pos = callback_map.find(channel);
356 if (pos != callback_map.end())
358 log_callbacks = pos->second;
361 ::memset (&log_callbacks, 0, sizeof(log_callbacks));
366 Log::EnableAllLogChannels
368 StreamSP &log_stream_sp,
369 uint32_t log_options,
370 const char **categories,
371 Stream *feedback_strm
374 CallbackMap &callback_map = GetCallbackMap ();
375 CallbackMapIter pos, end = callback_map.end();
377 for (pos = callback_map.begin(); pos != end; ++pos)
378 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
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)
384 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
390 Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
392 LogChannelMap &map = GetChannelMap ();
393 LogChannelMapIter pos, end = map.end();
394 for (pos = map.begin(); pos != end; ++pos)
396 const char *pos_channel_name = pos->first.GetCString();
397 if (channel_name && channel_name[0])
399 if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
401 matches.AppendString(pos_channel_name);
405 matches.AppendString(pos_channel_name);
411 Log::DisableAllLogChannels (Stream *feedback_strm)
413 CallbackMap &callback_map = GetCallbackMap ();
414 CallbackMapIter pos, end = callback_map.end();
415 const char *categories[1] = {NULL};
417 for (pos = callback_map.begin(); pos != end; ++pos)
418 pos->second.disable (categories, feedback_strm);
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)
423 channel_pos->second->Disable (categories, feedback_strm);
429 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
430 Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
436 DisableAllLogChannels (NULL);
440 Log::ListAllLogChannels (Stream *strm)
442 CallbackMap &callback_map = GetCallbackMap ();
443 LogChannelMap &channel_map = GetChannelMap ();
445 if (callback_map.empty() && channel_map.empty())
447 strm->PutCString ("No logging channels are currently registered.\n");
451 CallbackMapIter pos, end = callback_map.end();
452 for (pos = callback_map.begin(); pos != end; ++pos)
453 pos->second.list_categories (strm);
457 for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
459 LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
461 log_channel_sp->ListCategories (strm);
466 Log::GetVerbose() const
468 // FIXME: This has to be centralized between the stream and the log...
469 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
473 return m_stream_sp->GetVerbose();
477 //------------------------------------------------------------------
478 // Returns true if the debug flag bit is set in this stream.
479 //------------------------------------------------------------------
481 Log::GetDebug() const
484 return m_stream_sp->GetDebug();
490 LogChannel::FindPlugin (const char *plugin_name)
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())
498 ConstString const_plugin_name (plugin_name);
499 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
502 log_channel_sp.reset(create_callback());
505 // Cache the one and only loaded instance of each log channel
506 // plug-in after it has been loaded once.
507 channel_map[log_channel_name] = log_channel_sp;
513 // We have already loaded an instance of this log channel class,
514 // so just return the cached instance.
515 log_channel_sp = pos->second;
517 return log_channel_sp;
520 LogChannel::LogChannel () :
525 LogChannel::~LogChannel ()