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 <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" 33#include "lldb/Interpreter/Args.h" 34using namespace lldb; 35using namespace lldb_private; 36 37Log::Log () : 38 m_stream_sp(), 39 m_options(0), 40 m_mask_bits(0) 41{ 42} 43 44Log::Log (const 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; 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); 96 97 // Add a sequence ID if requested 98 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE)) 99 header.Printf ("%u ", ++g_sequence_id); 100 101 // Timestamp if requested 102 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) 103 { 104 struct timeval tv = TimeValue::Now().GetAsTimeVal(); 105 header.Printf ("%9ld.%6.6d ", tv.tv_sec, (int32_t)tv.tv_usec); 106 } 107 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()); 111 112 // Add the process and thread if requested 113 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) 114 { 115 std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID())); 116 if (!thread_name.empty()) 117 header.Printf ("%s ", thread_name.c_str()); 118 } 119 120 header.PrintfVarArg (format, args); 121 m_stream_sp->Printf("%s\n", header.GetData()); 122 123 if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE)) 124 Host::Backtrace (*m_stream_sp, 1024); 125 m_stream_sp->Flush(); 126 } 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{ 175 if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG)) 176 { 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{ 192 if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE)) 193 { 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{ 208 if (m_options.AllSet (bits)) 209 { 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{ 266 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE)) 267 { 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{ 282 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE)) 283 { 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 <ConstString, 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 ConstString &channel, const Log::Callbacks &log_callbacks) 341{ 342 GetCallbackMap().insert(std::make_pair(channel, log_callbacks)); 343} 344 345bool 346Log::UnregisterLogChannel (const ConstString &channel) 347{ 348 return GetCallbackMap().erase(channel) != 0; 349} 350 351bool 352Log::GetLogChannelCallbacks (const ConstString &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 } 361 ::memset (&log_callbacks, 0, sizeof(log_callbacks)); 362 return false; 363} 364 365void 366Log::EnableAllLogChannels 367( 368 StreamSP &log_stream_sp, 369 uint32_t log_options, 370 const char **categories, 371 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) 378 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm); 379 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 { 384 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories); 385 } 386 387} 388 389void 390Log::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 411Log::DisableAllLogChannels (Stream *feedback_strm) 412{ 413 CallbackMap &callback_map = GetCallbackMap (); 414 CallbackMapIter pos, end = callback_map.end(); 415 const char *categories[1] = {NULL}; 416 417 for (pos = callback_map.begin(); pos != end; ++pos) 418 pos->second.disable (categories, feedback_strm); 419 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); 424} 425 426void 427Log::Initialize() 428{ 429 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories }; 430 Log::RegisterLogChannel (ConstString("lldb"), log_callbacks); 431} 432 433void 434Log::Terminate () 435{ 436 DisableAllLogChannels (NULL); 437} 438 439void 440Log::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{ 468 // 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 472 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 ConstString const_plugin_name (plugin_name); 499 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name); 500 if (create_callback) 501 { 502 log_channel_sp.reset(create_callback()); 503 if (log_channel_sp) 504 { 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; 508 } 509 } 510 } 511 else 512 { 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; 516 } 517 return log_channel_sp; 518} 519 520LogChannel::LogChannel () : 521 m_log_ap () 522{ 523} 524 525LogChannel::~LogChannel () 526{ 527} 528 529 530