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" 34 using namespace lldb; 35 using namespace lldb_private; 36 37 Log::Log () : 38 m_stream_sp(), 39 m_options(0), 40 m_mask_bits(0) 41 { 42 } 43 44 Log::Log (const StreamSP &stream_sp) : 45 m_stream_sp(stream_sp), 46 m_options(0), 47 m_mask_bits(0) 48 { 49 } 50 51 Log::~Log () 52 { 53 } 54 55 Flags & 56 Log::GetOptions() 57 { 58 return m_options; 59 } 60 61 const Flags & 62 Log::GetOptions() const 63 { 64 return m_options; 65 } 66 67 Flags & 68 Log::GetMask() 69 { 70 return m_mask_bits; 71 } 72 73 const Flags & 74 Log::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 //---------------------------------------------------------------------- 85 void 86 Log::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 130 void 131 Log::PutCString (const char *cstr) 132 { 133 Printf ("%s", cstr); 134 } 135 136 137 //---------------------------------------------------------------------- 138 // Simple variable argument logging with flags. 139 //---------------------------------------------------------------------- 140 void 141 Log::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 149 void 150 Log::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 //---------------------------------------------------------------------- 159 void 160 Log::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 //---------------------------------------------------------------------- 172 void 173 Log::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 //---------------------------------------------------------------------- 189 void 190 Log::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 //---------------------------------------------------------------------- 205 void 206 Log::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 //---------------------------------------------------------------------- 221 void 222 Log::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 //---------------------------------------------------------------------- 241 void 242 Log::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 //---------------------------------------------------------------------- 263 void 264 Log::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 //---------------------------------------------------------------------- 279 void 280 Log::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 //---------------------------------------------------------------------- 300 void 301 Log::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 316 typedef std::map <ConstString, Log::Callbacks> CallbackMap; 317 typedef CallbackMap::iterator CallbackMapIter; 318 319 typedef std::map <ConstString, LogChannelSP> LogChannelMap; 320 typedef LogChannelMap::iterator LogChannelMapIter; 321 322 323 // Surround our callback map with a singleton function so we don't have any 324 // global initializers. 325 static CallbackMap & 326 GetCallbackMap () 327 { 328 static CallbackMap g_callback_map; 329 return g_callback_map; 330 } 331 332 static LogChannelMap & 333 GetChannelMap () 334 { 335 static LogChannelMap g_channel_map; 336 return g_channel_map; 337 } 338 339 void 340 Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks) 341 { 342 GetCallbackMap().insert(std::make_pair(channel, log_callbacks)); 343 } 344 345 bool 346 Log::UnregisterLogChannel (const ConstString &channel) 347 { 348 return GetCallbackMap().erase(channel) != 0; 349 } 350 351 bool 352 Log::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 365 void 366 Log::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 389 void 390 Log::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 410 void 411 Log::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 426 void 427 Log::Initialize() 428 { 429 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories }; 430 Log::RegisterLogChannel (ConstString("lldb"), log_callbacks); 431 } 432 433 void 434 Log::Terminate () 435 { 436 DisableAllLogChannels (NULL); 437 } 438 439 void 440 Log::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 465 bool 466 Log::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 //------------------------------------------------------------------ 480 bool 481 Log::GetDebug() const 482 { 483 if (m_stream_sp) 484 return m_stream_sp->GetDebug(); 485 return false; 486 } 487 488 489 LogChannelSP 490 LogChannel::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 520 LogChannel::LogChannel () : 521 m_log_ap () 522 { 523 } 524 525 LogChannel::~LogChannel () 526 { 527 } 528 529 530