lldb-log.cpp revision 926060e198137f8a64face70455324a8cd4362a5
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().Get(); 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().Get(); 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().Get())) 105 return log; 106 return NULL; 107} 108 109void 110lldb_private::DisableLog (Args &args, Stream *feedback_strm) 111{ 112 Log *log = LogAccessor (true, NULL); 113 uint32_t flag_bits; 114 115 if (log) 116 { 117 flag_bits = log->GetMask().Get(); 118 const size_t argc = args.GetArgumentCount (); 119 for (size_t i = 0; i < argc; ++i) 120 { 121 const char *arg = args.GetArgumentAtIndex (i); 122 123 if (strcasecmp(arg, "all") == 0 ) flag_bits &= ~LIBLLDB_LOG_ALL; 124 else if (strcasecmp(arg, "api") == 0) flag_bits &= ~LIBLLDB_LOG_API; 125 else if (strcasestr(arg, "break") == arg) flag_bits &= ~LIBLLDB_LOG_BREAKPOINTS; 126 else if (strcasecmp(arg, "default") == 0 ) flag_bits &= ~LIBLLDB_LOG_DEFAULT; 127 else if (strcasestr(arg, "event") == arg) flag_bits &= ~LIBLLDB_LOG_EVENTS; 128 else if (strcasestr(arg, "expr") == arg) flag_bits &= ~LIBLLDB_LOG_EXPRESSIONS; 129 else if (strcasestr(arg, "object") == arg) flag_bits &= ~LIBLLDB_LOG_OBJECT; 130 else if (strcasecmp(arg, "process") == 0 ) flag_bits &= ~LIBLLDB_LOG_PROCESS; 131 else if (strcasecmp(arg, "shlib") == 0 ) flag_bits &= ~LIBLLDB_LOG_SHLIB; 132 else if (strcasecmp(arg, "state") == 0 ) flag_bits &= ~LIBLLDB_LOG_STATE; 133 else if (strcasecmp(arg, "step") == 0 ) flag_bits &= ~LIBLLDB_LOG_STEP; 134 else if (strcasecmp(arg, "thread") == 0 ) flag_bits &= ~LIBLLDB_LOG_THREAD; 135 else if (strcasecmp(arg, "verbose") == 0 ) flag_bits &= ~LIBLLDB_LOG_VERBOSE; 136 else if (strcasestr(arg, "watch") == arg) flag_bits &= ~LIBLLDB_LOG_WATCHPOINTS; 137 else if (strcasestr(arg, "temp") == arg) flag_bits &= ~LIBLLDB_LOG_TEMPORARY; 138 else if (strcasestr(arg, "comm") == arg) flag_bits &= ~LIBLLDB_LOG_COMMUNICATION; 139 else if (strcasestr(arg, "conn") == arg) flag_bits &= ~LIBLLDB_LOG_CONNECTION; 140 else if (strcasestr(arg, "host") == arg) flag_bits &= ~LIBLLDB_LOG_HOST; 141 else if (strcasestr(arg, "unwind") == arg) flag_bits &= ~LIBLLDB_LOG_UNWIND; 142 else 143 { 144 feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg); 145 ListLogCategories (feedback_strm); 146 return; 147 } 148 149 } 150 if (flag_bits == 0) 151 LogAccessor (false, NULL); 152 else 153 log->GetMask().Reset (flag_bits); 154 } 155 156 return; 157} 158 159Log * 160lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm) 161{ 162 // Try see if there already is a log - that way we can reuse its settings. 163 // We could reuse the log in toto, but we don't know that the stream is the same. 164 uint32_t flag_bits; 165 Log* log = LogAccessor (true, NULL); 166 if (log) 167 flag_bits = log->GetMask().Get(); 168 else 169 flag_bits = 0; 170 171 // Now make a new log with this stream. 172 log = LogAccessor (false, &log_stream_sp); 173 if (log) 174 { 175 bool got_unknown_category = false; 176 const size_t argc = args.GetArgumentCount(); 177 for (size_t i=0; i<argc; ++i) 178 { 179 const char *arg = args.GetArgumentAtIndex(i); 180 181 if (strcasecmp(arg, "all") == 0 ) flag_bits |= LIBLLDB_LOG_ALL; 182 else if (strcasecmp(arg, "api") == 0) flag_bits |= LIBLLDB_LOG_API; 183 else if (strcasestr(arg, "break") == arg) flag_bits |= LIBLLDB_LOG_BREAKPOINTS; 184 else if (strcasecmp(arg, "default") == 0 ) flag_bits |= LIBLLDB_LOG_DEFAULT; 185 else if (strcasestr(arg, "event") == arg) flag_bits |= LIBLLDB_LOG_EVENTS; 186 else if (strcasestr(arg, "expr") == arg) flag_bits |= LIBLLDB_LOG_EXPRESSIONS; 187 else if (strcasestr(arg, "object") == arg) flag_bits |= LIBLLDB_LOG_OBJECT; 188 else if (strcasecmp(arg, "process") == 0 ) flag_bits |= LIBLLDB_LOG_PROCESS; 189 else if (strcasecmp(arg, "shlib") == 0 ) flag_bits |= LIBLLDB_LOG_SHLIB; 190 else if (strcasecmp(arg, "state") == 0 ) flag_bits |= LIBLLDB_LOG_STATE; 191 else if (strcasecmp(arg, "step") == 0 ) flag_bits |= LIBLLDB_LOG_STEP; 192 else if (strcasecmp(arg, "thread") == 0 ) flag_bits |= LIBLLDB_LOG_THREAD; 193 else if (strcasecmp(arg, "verbose") == 0 ) flag_bits |= LIBLLDB_LOG_VERBOSE; 194 else if (strcasestr(arg, "watch") == arg) flag_bits |= LIBLLDB_LOG_WATCHPOINTS; 195 else if (strcasestr(arg, "temp") == arg) flag_bits |= LIBLLDB_LOG_TEMPORARY; 196 else if (strcasestr(arg, "comm") == arg) flag_bits |= LIBLLDB_LOG_COMMUNICATION; 197 else if (strcasestr(arg, "conn") == arg) flag_bits |= LIBLLDB_LOG_CONNECTION; 198 else if (strcasestr(arg, "host") == arg) flag_bits |= LIBLLDB_LOG_HOST; 199 else if (strcasestr(arg, "unwind") == arg) flag_bits |= LIBLLDB_LOG_UNWIND; 200 else 201 { 202 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 203 if (got_unknown_category == false) 204 { 205 got_unknown_category = true; 206 ListLogCategories (feedback_strm); 207 return log; 208 } 209 } 210 } 211 212 log->GetMask().Reset(flag_bits); 213 log->GetOptions().Reset(log_options); 214 } 215 return log; 216} 217 218 219void 220lldb_private::ListLogCategories (Stream *strm) 221{ 222 strm->Printf("Logging categories for 'lldb':\n" 223 "\tall - turn on all available logging categories\n" 224 "\tapi - enable logging of API calls and return values\n" 225 "\tdefault - enable the default set of logging categories for liblldb\n" 226 "\tbreak - log breakpoints\n" 227 "\tevents - log broadcaster, listener and event queue activities\n" 228 "\texpr - log expressions\n" 229 "\tobject - log object construction/destruction for important objects\n" 230 "\tprocess - log process events and activities\n" 231 "\tthread - log thread events and activities\n" 232 "\tshlib - log shared library related activities\n" 233 "\tstate - log private and public process state changes\n" 234 "\tstep - log step related activities\n" 235 "\tunwind - log stack unwind activities\n" 236 "\tverbose - enable verbose loggging\n" 237 "\twatch - log watchpoint related activities\n"); 238} 239