lldb-log.cpp revision 8280cbe80c79bc206335831dd732e0f9fb69c519
1//===-- lldb-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-private-log.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "lldb/Interpreter/Args.h" 17#include "lldb/Core/Log.h" 18#include "lldb/Core/StreamFile.h" 19#include <string.h> 20 21using namespace lldb; 22using namespace lldb_private; 23 24 25static Log * 26LogAccessor (bool get, StreamSP *stream_sp_ptr) 27{ 28 static Log* g_log = NULL; // Leak for now as auto_ptr was being cleaned up 29 // by global constructors before other threads 30 // were done with it. 31 if (!get) 32 { 33 if (g_log) 34 delete g_log; 35 if (stream_sp_ptr) 36 g_log = new Log (*stream_sp_ptr); 37 else 38 g_log = NULL; 39 } 40 41 return g_log; 42 43} 44 45uint32_t 46lldb_private::GetLogMask () 47{ 48 Log *log = LogAccessor (true, NULL); 49 if (log) 50 return log->GetMask().GetAllFlagBits(); 51 return 0; 52} 53 54bool 55lldb_private::IsLogVerbose () 56{ 57 uint32_t mask = GetLogMask(); 58 return (mask & LIBLLDB_LOG_VERBOSE); 59} 60 61Log * 62lldb_private::GetLogIfAllCategoriesSet (uint32_t mask) 63{ 64 Log *log = LogAccessor (true, NULL); 65 if (log && mask) 66 { 67 uint32_t log_mask = log->GetMask().GetAllFlagBits(); 68 if ((log_mask & mask) != mask) 69 return NULL; 70 } 71 return log; 72} 73 74void 75lldb_private::LogIfAllCategoriesSet (uint32_t mask, const char *format, ...) 76{ 77 Log *log = GetLogIfAllCategoriesSet (mask); 78 if (log) 79 { 80 va_list args; 81 va_start (args, format); 82 log->VAPrintf (format, args); 83 va_end (args); 84 } 85} 86 87void 88lldb_private::LogIfAnyCategoriesSet (uint32_t mask, const char *format, ...) 89{ 90 Log *log = GetLogIfAnyCategoriesSet (mask); 91 if (log) 92 { 93 va_list args; 94 va_start (args, format); 95 log->VAPrintf (format, args); 96 va_end (args); 97 } 98} 99 100Log * 101lldb_private::GetLogIfAnyCategoriesSet (uint32_t mask) 102{ 103 Log *log = LogAccessor (true, NULL); 104 if (log && mask && (mask & log->GetMask().GetAllFlagBits())) 105 return log; 106 return NULL; 107} 108 109void 110lldb_private::DisableLog () 111{ 112 LogAccessor (false, NULL); 113} 114 115 116Log * 117lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm) 118{ 119 // Try see if there already is a log - that way we can reuse its settings. 120 // We could reuse the log in toto, but we don't know that the stream is the same. 121 uint32_t flag_bits; 122 Log* log = LogAccessor (true, NULL); 123 if (log) 124 flag_bits = log->GetMask().GetAllFlagBits(); 125 else 126 flag_bits = 0; 127 128 // Now make a new log with this stream. 129 log = LogAccessor (false, &log_stream_sp); 130 if (log) 131 { 132 bool got_unknown_category = false; 133 const size_t argc = args.GetArgumentCount(); 134 for (size_t i=0; i<argc; ++i) 135 { 136 const char *arg = args.GetArgumentAtIndex(i); 137 138 if (strcasecmp(arg, "all") == 0 ) flag_bits |= LIBLLDB_LOG_ALL; 139 else if (strcasestr(arg, "break") == arg) flag_bits |= LIBLLDB_LOG_BREAKPOINTS; 140 else if (strcasecmp(arg, "default") == 0 ) flag_bits |= LIBLLDB_LOG_DEFAULT; 141 else if (strcasestr(arg, "event") == arg) flag_bits |= LIBLLDB_LOG_EVENTS; 142 else if (strcasestr(arg, "expr") == arg) flag_bits |= LIBLLDB_LOG_EXPRESSIONS; 143 else if (strcasestr(arg, "object") == arg) flag_bits |= LIBLLDB_LOG_OBJECT; 144 else if (strcasecmp(arg, "process") == 0 ) flag_bits |= LIBLLDB_LOG_PROCESS; 145 else if (strcasecmp(arg, "shlib") == 0 ) flag_bits |= LIBLLDB_LOG_SHLIB; 146 else if (strcasecmp(arg, "state") == 0 ) flag_bits |= LIBLLDB_LOG_STATE; 147 else if (strcasecmp(arg, "step") == 0 ) flag_bits |= LIBLLDB_LOG_STEP; 148 else if (strcasecmp(arg, "thread") == 0 ) flag_bits |= LIBLLDB_LOG_THREAD; 149 else if (strcasecmp(arg, "verbose") == 0 ) flag_bits |= LIBLLDB_LOG_VERBOSE; 150 else if (strcasestr(arg, "watch") == arg) flag_bits |= LIBLLDB_LOG_WATCHPOINTS; 151 else if (strcasestr(arg, "temp") == arg) flag_bits |= LIBLLDB_LOG_TEMPORARY; 152 else if (strcasestr(arg, "comm") == arg) flag_bits |= LIBLLDB_LOG_COMMUNICATION; 153 else if (strcasestr(arg, "conn") == arg) flag_bits |= LIBLLDB_LOG_CONNECTION; 154 else if (strcasestr(arg, "host") == arg) flag_bits |= LIBLLDB_LOG_HOST; 155 else if (strcasestr(arg, "unwind") == arg) flag_bits |= LIBLLDB_LOG_UNWIND; 156 else 157 { 158 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 159 if (got_unknown_category == false) 160 { 161 got_unknown_category = true; 162 ListLogCategories (feedback_strm); 163 return log; 164 } 165 } 166 } 167 168 log->GetMask().SetAllFlagBits(flag_bits); 169 log->GetOptions().SetAllFlagBits(log_options); 170 } 171 return log; 172} 173 174 175void 176lldb_private::ListLogCategories (Stream *strm) 177{ 178 strm->Printf("Logging categories for 'lldb':\n" 179 "\tall - turn on all available logging categories\n" 180 "\tdefault - enable the default set of logging categories for liblldb\n" 181 "\tbreak - log breakpoints\n" 182 "\tevents - log broadcaster, listener and event queue activities\n" 183 "\texpr - log expressions\n" 184 "\tobject - log object construction/destruction for important objects\n" 185 "\tprocess - log process events and activities\n" 186 "\tthread - log thread events and activities\n" 187 "\tshlib - log shared library related activities\n" 188 "\tstate - log private and public process state changes\n" 189 "\tstep - log step related activities\n" 190 "\tunwind - log stack unwind activities\n" 191 "\tverbose - enable verbose loggging\n" 192 "\twatch - log watchpoint related activities\n"); 193} 194