Log.cpp revision 263363
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 <stdio.h> 14#include <stdarg.h> 15#include <stdlib.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" 31#include "lldb/Interpreter/Args.h" 32using namespace lldb; 33using namespace lldb_private; 34 35Log::Log () : 36 m_stream_sp(), 37 m_options(0), 38 m_mask_bits(0) 39{ 40} 41 42Log::Log (const 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; 90 // 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); 94 95 // Add a sequence ID if requested 96 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE)) 97 header.Printf ("%u ", ++g_sequence_id); 98 99 // Timestamp if requested 100 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) 101 { 102 TimeValue now = TimeValue::Now(); 103 header.Printf ("%9d.%6.6d ", now.seconds(), now.nanoseconds()); 104 } 105 106 // Add the process and thread if requested 107 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD)) 108 header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID()); 109 110 // Add the process and thread if requested 111 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) 112 { 113 std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID())); 114 if (!thread_name.empty()) 115 header.Printf ("%s ", thread_name.c_str()); 116 } 117 118 header.PrintfVarArg (format, args); 119 m_stream_sp->Printf("%s\n", header.GetData()); 120 121 if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE)) 122 Host::Backtrace (*m_stream_sp, 1024); 123 m_stream_sp->Flush(); 124 } 125} 126 127 128void 129Log::PutCString (const char *cstr) 130{ 131 Printf ("%s", cstr); 132} 133 134 135//---------------------------------------------------------------------- 136// Simple variable argument logging with flags. 137//---------------------------------------------------------------------- 138void 139Log::Printf(const char *format, ...) 140{ 141 va_list args; 142 va_start (args, format); 143 PrintfWithFlagsVarArg (0, format, args); 144 va_end (args); 145} 146 147void 148Log::VAPrintf (const char *format, va_list args) 149{ 150 PrintfWithFlagsVarArg (0, format, args); 151} 152 153 154//---------------------------------------------------------------------- 155// Simple variable argument logging with flags. 156//---------------------------------------------------------------------- 157void 158Log::PrintfWithFlags (uint32_t flags, const char *format, ...) 159{ 160 va_list args; 161 va_start (args, format); 162 PrintfWithFlagsVarArg (flags, format, args); 163 va_end (args); 164} 165 166//---------------------------------------------------------------------- 167// Print debug strings if and only if the global debug option is set to 168// a non-zero value. 169//---------------------------------------------------------------------- 170void 171Log::Debug (const char *format, ...) 172{ 173 if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG)) 174 { 175 va_list args; 176 va_start (args, format); 177 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args); 178 va_end (args); 179 } 180} 181 182 183//---------------------------------------------------------------------- 184// Print debug strings if and only if the global debug option is set to 185// a non-zero value. 186//---------------------------------------------------------------------- 187void 188Log::DebugVerbose (const char *format, ...) 189{ 190 if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE)) 191 { 192 va_list args; 193 va_start (args, format); 194 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args); 195 va_end (args); 196 } 197} 198 199 200//---------------------------------------------------------------------- 201// Log only if all of the bits are set 202//---------------------------------------------------------------------- 203void 204Log::LogIf (uint32_t bits, const char *format, ...) 205{ 206 if (m_options.AllSet (bits)) 207 { 208 va_list args; 209 va_start (args, format); 210 PrintfWithFlagsVarArg (0, format, args); 211 va_end (args); 212 } 213} 214 215 216//---------------------------------------------------------------------- 217// Printing of errors that are not fatal. 218//---------------------------------------------------------------------- 219void 220Log::Error (const char *format, ...) 221{ 222 char *arg_msg = NULL; 223 va_list args; 224 va_start (args, format); 225 ::vasprintf (&arg_msg, format, args); 226 va_end (args); 227 228 if (arg_msg != NULL) 229 { 230 PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg); 231 free (arg_msg); 232 } 233} 234 235//---------------------------------------------------------------------- 236// Printing of errors that ARE fatal. Exit with ERR exit code 237// immediately. 238//---------------------------------------------------------------------- 239void 240Log::FatalError (int err, const char *format, ...) 241{ 242 char *arg_msg = NULL; 243 va_list args; 244 va_start (args, format); 245 ::vasprintf (&arg_msg, format, args); 246 va_end (args); 247 248 if (arg_msg != NULL) 249 { 250 PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg); 251 ::free (arg_msg); 252 } 253 ::exit (err); 254} 255 256 257//---------------------------------------------------------------------- 258// Printing of warnings that are not fatal only if verbose mode is 259// enabled. 260//---------------------------------------------------------------------- 261void 262Log::Verbose (const char *format, ...) 263{ 264 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE)) 265 { 266 va_list args; 267 va_start (args, format); 268 PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args); 269 va_end (args); 270 } 271} 272 273//---------------------------------------------------------------------- 274// Printing of warnings that are not fatal only if verbose mode is 275// enabled. 276//---------------------------------------------------------------------- 277void 278Log::WarningVerbose (const char *format, ...) 279{ 280 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE)) 281 { 282 char *arg_msg = NULL; 283 va_list args; 284 va_start (args, format); 285 ::vasprintf (&arg_msg, format, args); 286 va_end (args); 287 288 if (arg_msg != NULL) 289 { 290 PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg); 291 free (arg_msg); 292 } 293 } 294} 295//---------------------------------------------------------------------- 296// Printing of warnings that are not fatal. 297//---------------------------------------------------------------------- 298void 299Log::Warning (const char *format, ...) 300{ 301 char *arg_msg = NULL; 302 va_list args; 303 va_start (args, format); 304 ::vasprintf (&arg_msg, format, args); 305 va_end (args); 306 307 if (arg_msg != NULL) 308 { 309 PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg); 310 free (arg_msg); 311 } 312} 313 314typedef std::map <ConstString, Log::Callbacks> CallbackMap; 315typedef CallbackMap::iterator CallbackMapIter; 316 317typedef std::map <ConstString, LogChannelSP> LogChannelMap; 318typedef LogChannelMap::iterator LogChannelMapIter; 319 320 321// Surround our callback map with a singleton function so we don't have any 322// global initializers. 323static CallbackMap & 324GetCallbackMap () 325{ 326 static CallbackMap g_callback_map; 327 return g_callback_map; 328} 329 330static LogChannelMap & 331GetChannelMap () 332{ 333 static LogChannelMap g_channel_map; 334 return g_channel_map; 335} 336 337void 338Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks) 339{ 340 GetCallbackMap().insert(std::make_pair(channel, log_callbacks)); 341} 342 343bool 344Log::UnregisterLogChannel (const ConstString &channel) 345{ 346 return GetCallbackMap().erase(channel) != 0; 347} 348 349bool 350Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks) 351{ 352 CallbackMap &callback_map = GetCallbackMap (); 353 CallbackMapIter pos = callback_map.find(channel); 354 if (pos != callback_map.end()) 355 { 356 log_callbacks = pos->second; 357 return true; 358 } 359 ::memset (&log_callbacks, 0, sizeof(log_callbacks)); 360 return false; 361} 362 363void 364Log::EnableAllLogChannels 365( 366 StreamSP &log_stream_sp, 367 uint32_t log_options, 368 const char **categories, 369 Stream *feedback_strm 370) 371{ 372 CallbackMap &callback_map = GetCallbackMap (); 373 CallbackMapIter pos, end = callback_map.end(); 374 375 for (pos = callback_map.begin(); pos != end; ++pos) 376 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm); 377 378 LogChannelMap &channel_map = GetChannelMap (); 379 LogChannelMapIter channel_pos, channel_end = channel_map.end(); 380 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos) 381 { 382 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories); 383 } 384 385} 386 387void 388Log::AutoCompleteChannelName (const char *channel_name, StringList &matches) 389{ 390 LogChannelMap &map = GetChannelMap (); 391 LogChannelMapIter pos, end = map.end(); 392 for (pos = map.begin(); pos != end; ++pos) 393 { 394 const char *pos_channel_name = pos->first.GetCString(); 395 if (channel_name && channel_name[0]) 396 { 397 if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name)) 398 { 399 matches.AppendString(pos_channel_name); 400 } 401 } 402 else 403 matches.AppendString(pos_channel_name); 404 405 } 406} 407 408void 409Log::DisableAllLogChannels (Stream *feedback_strm) 410{ 411 CallbackMap &callback_map = GetCallbackMap (); 412 CallbackMapIter pos, end = callback_map.end(); 413 const char *categories[1] = {NULL}; 414 415 for (pos = callback_map.begin(); pos != end; ++pos) 416 pos->second.disable (categories, feedback_strm); 417 418 LogChannelMap &channel_map = GetChannelMap (); 419 LogChannelMapIter channel_pos, channel_end = channel_map.end(); 420 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos) 421 channel_pos->second->Disable (categories, feedback_strm); 422} 423 424void 425Log::Initialize() 426{ 427 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories }; 428 Log::RegisterLogChannel (ConstString("lldb"), log_callbacks); 429} 430 431void 432Log::Terminate () 433{ 434 DisableAllLogChannels (NULL); 435} 436 437void 438Log::ListAllLogChannels (Stream *strm) 439{ 440 CallbackMap &callback_map = GetCallbackMap (); 441 LogChannelMap &channel_map = GetChannelMap (); 442 443 if (callback_map.empty() && channel_map.empty()) 444 { 445 strm->PutCString ("No logging channels are currently registered.\n"); 446 return; 447 } 448 449 CallbackMapIter pos, end = callback_map.end(); 450 for (pos = callback_map.begin(); pos != end; ++pos) 451 pos->second.list_categories (strm); 452 453 uint32_t idx = 0; 454 const char *name; 455 for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx) 456 { 457 LogChannelSP log_channel_sp(LogChannel::FindPlugin (name)); 458 if (log_channel_sp) 459 log_channel_sp->ListCategories (strm); 460 } 461} 462 463bool 464Log::GetVerbose() const 465{ 466 // FIXME: This has to be centralized between the stream and the log... 467 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE)) 468 return true; 469 470 if (m_stream_sp) 471 return m_stream_sp->GetVerbose(); 472 return false; 473} 474 475//------------------------------------------------------------------ 476// Returns true if the debug flag bit is set in this stream. 477//------------------------------------------------------------------ 478bool 479Log::GetDebug() const 480{ 481 if (m_stream_sp) 482 return m_stream_sp->GetDebug(); 483 return false; 484} 485 486 487LogChannelSP 488LogChannel::FindPlugin (const char *plugin_name) 489{ 490 LogChannelSP log_channel_sp; 491 LogChannelMap &channel_map = GetChannelMap (); 492 ConstString log_channel_name (plugin_name); 493 LogChannelMapIter pos = channel_map.find (log_channel_name); 494 if (pos == channel_map.end()) 495 { 496 ConstString const_plugin_name (plugin_name); 497 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (const_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_ap () 520{ 521} 522 523LogChannel::~LogChannel () 524{ 525} 526 527 528