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