Alexander Shaposhnikov | 696bd63 | 2016-11-26 05:23:44 +0000 | [diff] [blame^] | 1 | //===-- Logging.cpp ---------------------------------------------*- C++ -*-===// |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 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 | |
Zachary Turner | 3294de2 | 2015-03-18 18:20:42 +0000 | [diff] [blame] | 10 | #include "lldb/Core/Logging.h" |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 11 | |
| 12 | // C Includes |
| 13 | // C++ Includes |
Zachary Turner | 4171da5 | 2014-09-19 20:12:32 +0000 | [diff] [blame] | 14 | #include <atomic> |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 15 | #include <cstring> |
Eugene Zelenko | 8918372 | 2016-03-11 21:55:47 +0000 | [diff] [blame] | 16 | |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 17 | // Other libraries and framework includes |
| 18 | // Project includes |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 19 | #include "lldb/Core/Log.h" |
| 20 | #include "lldb/Core/StreamFile.h" |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 21 | #include "lldb/Interpreter/Args.h" |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 22 | |
| 23 | using namespace lldb; |
| 24 | using namespace lldb_private; |
| 25 | |
Greg Clayton | 2d4edfb | 2010-11-06 01:53:30 +0000 | [diff] [blame] | 26 | // We want to avoid global constructors where code needs to be run so here we |
| 27 | // control access to our static g_log_sp by hiding it in a singleton function |
Zachary Turner | 3294de2 | 2015-03-18 18:20:42 +0000 | [diff] [blame] | 28 | // that will construct the static g_lob_sp the first time this function is |
Greg Clayton | 2d4edfb | 2010-11-06 01:53:30 +0000 | [diff] [blame] | 29 | // called. |
Greg Clayton | 5160ce5 | 2013-03-27 23:08:40 +0000 | [diff] [blame] | 30 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 31 | static std::atomic<bool> g_log_enabled{false}; |
| 32 | static Log *g_log = nullptr; |
Eugene Zelenko | 8918372 | 2016-03-11 21:55:47 +0000 | [diff] [blame] | 33 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 34 | static Log *GetLog() { |
| 35 | if (!g_log_enabled) |
Eugene Zelenko | 8918372 | 2016-03-11 21:55:47 +0000 | [diff] [blame] | 36 | return nullptr; |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 37 | return g_log; |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 38 | } |
| 39 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 40 | uint32_t lldb_private::GetLogMask() { |
| 41 | Log *log(GetLog()); |
| 42 | if (log) |
| 43 | return log->GetMask().Get(); |
| 44 | return 0; |
| 45 | } |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 46 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 47 | bool lldb_private::IsLogVerbose() { |
| 48 | uint32_t mask = GetLogMask(); |
| 49 | return (mask & LIBLLDB_LOG_VERBOSE); |
| 50 | } |
Greg Clayton | 99d0faf | 2010-11-18 23:32:35 +0000 | [diff] [blame] | 51 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 52 | Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) { |
| 53 | Log *log(GetLog()); |
| 54 | if (log && mask) { |
| 55 | uint32_t log_mask = log->GetMask().Get(); |
| 56 | if ((log_mask & mask) != mask) |
| 57 | return nullptr; |
| 58 | } |
| 59 | return log; |
| 60 | } |
| 61 | |
| 62 | void lldb_private::LogIfAllCategoriesSet(uint32_t mask, const char *format, |
| 63 | ...) { |
| 64 | Log *log(GetLogIfAllCategoriesSet(mask)); |
| 65 | if (log) { |
| 66 | va_list args; |
| 67 | va_start(args, format); |
| 68 | log->VAPrintf(format, args); |
| 69 | va_end(args); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | void lldb_private::LogIfAnyCategoriesSet(uint32_t mask, const char *format, |
| 74 | ...) { |
| 75 | Log *log(GetLogIfAnyCategoriesSet(mask)); |
| 76 | if (log != nullptr) { |
| 77 | va_list args; |
| 78 | va_start(args, format); |
| 79 | log->VAPrintf(format, args); |
| 80 | va_end(args); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) { |
| 85 | Log *log(GetLog()); |
| 86 | if (log != nullptr && mask && (mask & log->GetMask().Get())) |
| 87 | return log; |
| 88 | return nullptr; |
| 89 | } |
| 90 | |
| 91 | void lldb_private::DisableLog(const char **categories, Stream *feedback_strm) { |
| 92 | Log *log(GetLog()); |
| 93 | |
| 94 | if (log != nullptr) { |
| 95 | uint32_t flag_bits = 0; |
Zachary Turner | 691405b | 2016-10-03 22:51:09 +0000 | [diff] [blame] | 96 | if (categories && categories[0]) { |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 97 | flag_bits = log->GetMask().Get(); |
| 98 | for (size_t i = 0; categories[i] != nullptr; ++i) { |
| 99 | const char *arg = categories[i]; |
| 100 | |
| 101 | if (0 == ::strcasecmp(arg, "all")) |
| 102 | flag_bits &= ~LIBLLDB_LOG_ALL; |
| 103 | else if (0 == ::strcasecmp(arg, "api")) |
| 104 | flag_bits &= ~LIBLLDB_LOG_API; |
| 105 | else if (0 == ::strncasecmp(arg, "break", 5)) |
| 106 | flag_bits &= ~LIBLLDB_LOG_BREAKPOINTS; |
| 107 | else if (0 == ::strcasecmp(arg, "commands")) |
| 108 | flag_bits &= ~LIBLLDB_LOG_COMMANDS; |
| 109 | else if (0 == ::strcasecmp(arg, "default")) |
| 110 | flag_bits &= ~LIBLLDB_LOG_DEFAULT; |
| 111 | else if (0 == ::strcasecmp(arg, "dyld")) |
| 112 | flag_bits &= ~LIBLLDB_LOG_DYNAMIC_LOADER; |
| 113 | else if (0 == ::strncasecmp(arg, "event", 5)) |
| 114 | flag_bits &= ~LIBLLDB_LOG_EVENTS; |
| 115 | else if (0 == ::strncasecmp(arg, "expr", 4)) |
| 116 | flag_bits &= ~LIBLLDB_LOG_EXPRESSIONS; |
| 117 | else if (0 == ::strncasecmp(arg, "object", 6)) |
| 118 | flag_bits &= ~LIBLLDB_LOG_OBJECT; |
| 119 | else if (0 == ::strcasecmp(arg, "process")) |
| 120 | flag_bits &= ~LIBLLDB_LOG_PROCESS; |
| 121 | else if (0 == ::strcasecmp(arg, "platform")) |
| 122 | flag_bits &= ~LIBLLDB_LOG_PLATFORM; |
| 123 | else if (0 == ::strcasecmp(arg, "script")) |
| 124 | flag_bits &= ~LIBLLDB_LOG_SCRIPT; |
| 125 | else if (0 == ::strcasecmp(arg, "state")) |
| 126 | flag_bits &= ~LIBLLDB_LOG_STATE; |
| 127 | else if (0 == ::strcasecmp(arg, "step")) |
| 128 | flag_bits &= ~LIBLLDB_LOG_STEP; |
| 129 | else if (0 == ::strcasecmp(arg, "thread")) |
| 130 | flag_bits &= ~LIBLLDB_LOG_THREAD; |
| 131 | else if (0 == ::strcasecmp(arg, "target")) |
| 132 | flag_bits &= ~LIBLLDB_LOG_TARGET; |
| 133 | else if (0 == ::strcasecmp(arg, "verbose")) |
| 134 | flag_bits &= ~LIBLLDB_LOG_VERBOSE; |
| 135 | else if (0 == ::strncasecmp(arg, "watch", 5)) |
| 136 | flag_bits &= ~LIBLLDB_LOG_WATCHPOINTS; |
| 137 | else if (0 == ::strncasecmp(arg, "temp", 4)) |
| 138 | flag_bits &= ~LIBLLDB_LOG_TEMPORARY; |
| 139 | else if (0 == ::strncasecmp(arg, "comm", 4)) |
| 140 | flag_bits &= ~LIBLLDB_LOG_COMMUNICATION; |
| 141 | else if (0 == ::strncasecmp(arg, "conn", 4)) |
| 142 | flag_bits &= ~LIBLLDB_LOG_CONNECTION; |
| 143 | else if (0 == ::strncasecmp(arg, "host", 4)) |
| 144 | flag_bits &= ~LIBLLDB_LOG_HOST; |
| 145 | else if (0 == ::strncasecmp(arg, "unwind", 6)) |
| 146 | flag_bits &= ~LIBLLDB_LOG_UNWIND; |
| 147 | else if (0 == ::strncasecmp(arg, "types", 5)) |
| 148 | flag_bits &= ~LIBLLDB_LOG_TYPES; |
| 149 | else if (0 == ::strncasecmp(arg, "symbol", 6)) |
| 150 | flag_bits &= ~LIBLLDB_LOG_SYMBOLS; |
| 151 | else if (0 == ::strcasecmp(arg, "system-runtime")) |
| 152 | flag_bits &= ~LIBLLDB_LOG_SYSTEM_RUNTIME; |
| 153 | else if (0 == ::strncasecmp(arg, "module", 6)) |
| 154 | flag_bits &= ~LIBLLDB_LOG_MODULES; |
| 155 | else if (0 == ::strncasecmp(arg, "mmap", 4)) |
| 156 | flag_bits &= ~LIBLLDB_LOG_MMAP; |
| 157 | else if (0 == ::strcasecmp(arg, "os")) |
| 158 | flag_bits &= ~LIBLLDB_LOG_OS; |
| 159 | else if (0 == ::strcasecmp(arg, "jit")) |
| 160 | flag_bits &= ~LIBLLDB_LOG_JIT_LOADER; |
| 161 | else if (0 == ::strcasecmp(arg, "language")) |
| 162 | flag_bits &= ~LIBLLDB_LOG_LANGUAGE; |
| 163 | else if (0 == ::strncasecmp(arg, "formatters", 10)) |
| 164 | flag_bits &= ~LIBLLDB_LOG_DATAFORMATTERS; |
| 165 | else if (0 == ::strncasecmp(arg, "demangle", 8)) |
| 166 | flag_bits &= ~LIBLLDB_LOG_DEMANGLE; |
| 167 | else { |
| 168 | feedback_strm->Printf("error: unrecognized log category '%s'\n", |
| 169 | arg); |
| 170 | ListLogCategories(feedback_strm); |
| 171 | return; |
Caroline Tice | 20ad3c4 | 2010-10-29 21:48:37 +0000 | [diff] [blame] | 172 | } |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 173 | } |
Caroline Tice | 20ad3c4 | 2010-10-29 21:48:37 +0000 | [diff] [blame] | 174 | } |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 175 | log->GetMask().Reset(flag_bits); |
| 176 | if (flag_bits == 0) { |
| 177 | log->SetStream(lldb::StreamSP()); |
| 178 | g_log_enabled = false; |
| 179 | } |
| 180 | } |
Caroline Tice | 20ad3c4 | 2010-10-29 21:48:37 +0000 | [diff] [blame] | 181 | } |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 182 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 183 | Log *lldb_private::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, |
| 184 | const char **categories, Stream *feedback_strm) { |
| 185 | // Try see if there already is a log - that way we can reuse its settings. |
| 186 | // We could reuse the log in toto, but we don't know that the stream is the |
| 187 | // same. |
| 188 | uint32_t flag_bits; |
| 189 | if (g_log != nullptr) |
| 190 | flag_bits = g_log->GetMask().Get(); |
| 191 | else |
| 192 | flag_bits = 0; |
| 193 | |
| 194 | // Now make a new log with this stream if one was provided |
| 195 | if (log_stream_sp) { |
Eugene Zelenko | 8918372 | 2016-03-11 21:55:47 +0000 | [diff] [blame] | 196 | if (g_log != nullptr) |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 197 | g_log->SetStream(log_stream_sp); |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 198 | else |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 199 | g_log = new Log(log_stream_sp); |
| 200 | } |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 201 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 202 | if (g_log != nullptr) { |
| 203 | for (size_t i = 0; categories[i] != nullptr; ++i) { |
| 204 | const char *arg = categories[i]; |
| 205 | |
| 206 | if (0 == ::strcasecmp(arg, "all")) |
| 207 | flag_bits |= LIBLLDB_LOG_ALL; |
| 208 | else if (0 == ::strcasecmp(arg, "api")) |
| 209 | flag_bits |= LIBLLDB_LOG_API; |
| 210 | else if (0 == ::strncasecmp(arg, "break", 5)) |
| 211 | flag_bits |= LIBLLDB_LOG_BREAKPOINTS; |
| 212 | else if (0 == ::strcasecmp(arg, "commands")) |
| 213 | flag_bits |= LIBLLDB_LOG_COMMANDS; |
| 214 | else if (0 == ::strncasecmp(arg, "commu", 5)) |
| 215 | flag_bits |= LIBLLDB_LOG_COMMUNICATION; |
| 216 | else if (0 == ::strncasecmp(arg, "conn", 4)) |
| 217 | flag_bits |= LIBLLDB_LOG_CONNECTION; |
| 218 | else if (0 == ::strcasecmp(arg, "default")) |
| 219 | flag_bits |= LIBLLDB_LOG_DEFAULT; |
| 220 | else if (0 == ::strcasecmp(arg, "dyld")) |
| 221 | flag_bits |= LIBLLDB_LOG_DYNAMIC_LOADER; |
| 222 | else if (0 == ::strncasecmp(arg, "event", 5)) |
| 223 | flag_bits |= LIBLLDB_LOG_EVENTS; |
| 224 | else if (0 == ::strncasecmp(arg, "expr", 4)) |
| 225 | flag_bits |= LIBLLDB_LOG_EXPRESSIONS; |
| 226 | else if (0 == ::strncasecmp(arg, "host", 4)) |
| 227 | flag_bits |= LIBLLDB_LOG_HOST; |
| 228 | else if (0 == ::strncasecmp(arg, "mmap", 4)) |
| 229 | flag_bits |= LIBLLDB_LOG_MMAP; |
| 230 | else if (0 == ::strncasecmp(arg, "module", 6)) |
| 231 | flag_bits |= LIBLLDB_LOG_MODULES; |
| 232 | else if (0 == ::strncasecmp(arg, "object", 6)) |
| 233 | flag_bits |= LIBLLDB_LOG_OBJECT; |
| 234 | else if (0 == ::strcasecmp(arg, "os")) |
| 235 | flag_bits |= LIBLLDB_LOG_OS; |
| 236 | else if (0 == ::strcasecmp(arg, "platform")) |
| 237 | flag_bits |= LIBLLDB_LOG_PLATFORM; |
| 238 | else if (0 == ::strcasecmp(arg, "process")) |
| 239 | flag_bits |= LIBLLDB_LOG_PROCESS; |
| 240 | else if (0 == ::strcasecmp(arg, "script")) |
| 241 | flag_bits |= LIBLLDB_LOG_SCRIPT; |
| 242 | else if (0 == ::strcasecmp(arg, "state")) |
| 243 | flag_bits |= LIBLLDB_LOG_STATE; |
| 244 | else if (0 == ::strcasecmp(arg, "step")) |
| 245 | flag_bits |= LIBLLDB_LOG_STEP; |
| 246 | else if (0 == ::strncasecmp(arg, "symbol", 6)) |
| 247 | flag_bits |= LIBLLDB_LOG_SYMBOLS; |
| 248 | else if (0 == ::strcasecmp(arg, "system-runtime")) |
| 249 | flag_bits |= LIBLLDB_LOG_SYSTEM_RUNTIME; |
| 250 | else if (0 == ::strcasecmp(arg, "target")) |
| 251 | flag_bits |= LIBLLDB_LOG_TARGET; |
| 252 | else if (0 == ::strncasecmp(arg, "temp", 4)) |
| 253 | flag_bits |= LIBLLDB_LOG_TEMPORARY; |
| 254 | else if (0 == ::strcasecmp(arg, "thread")) |
| 255 | flag_bits |= LIBLLDB_LOG_THREAD; |
| 256 | else if (0 == ::strncasecmp(arg, "types", 5)) |
| 257 | flag_bits |= LIBLLDB_LOG_TYPES; |
| 258 | else if (0 == ::strncasecmp(arg, "unwind", 6)) |
| 259 | flag_bits |= LIBLLDB_LOG_UNWIND; |
| 260 | else if (0 == ::strcasecmp(arg, "verbose")) |
| 261 | flag_bits |= LIBLLDB_LOG_VERBOSE; |
| 262 | else if (0 == ::strncasecmp(arg, "watch", 5)) |
| 263 | flag_bits |= LIBLLDB_LOG_WATCHPOINTS; |
| 264 | else if (0 == ::strcasecmp(arg, "jit")) |
| 265 | flag_bits |= LIBLLDB_LOG_JIT_LOADER; |
| 266 | else if (0 == ::strcasecmp(arg, "language")) |
| 267 | flag_bits |= LIBLLDB_LOG_LANGUAGE; |
| 268 | else if (0 == ::strncasecmp(arg, "formatters", 10)) |
| 269 | flag_bits |= LIBLLDB_LOG_DATAFORMATTERS; |
| 270 | else if (0 == ::strncasecmp(arg, "demangle", 8)) |
| 271 | flag_bits |= LIBLLDB_LOG_DEMANGLE; |
| 272 | else { |
| 273 | feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); |
| 274 | ListLogCategories(feedback_strm); |
| 275 | return g_log; |
| 276 | } |
Greg Clayton | 2d4edfb | 2010-11-06 01:53:30 +0000 | [diff] [blame] | 277 | } |
| 278 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 279 | g_log->GetMask().Reset(flag_bits); |
| 280 | g_log->GetOptions().Reset(log_options); |
| 281 | } |
| 282 | g_log_enabled = true; |
| 283 | return g_log; |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 284 | } |
| 285 | |
Kate Stone | b9c1b51 | 2016-09-06 20:57:50 +0000 | [diff] [blame] | 286 | void lldb_private::ListLogCategories(Stream *strm) { |
| 287 | strm->Printf( |
| 288 | "Logging categories for 'lldb':\n" |
| 289 | " all - turn on all available logging categories\n" |
| 290 | " api - enable logging of API calls and return values\n" |
| 291 | " break - log breakpoints\n" |
| 292 | " commands - log command argument parsing\n" |
| 293 | " communication - log communication activities\n" |
| 294 | " connection - log connection details\n" |
| 295 | " default - enable the default set of logging categories for liblldb\n" |
| 296 | " demangle - log mangled names to catch demangler crashes\n" |
| 297 | " dyld - log shared library related activities\n" |
| 298 | " events - log broadcaster, listener and event queue activities\n" |
| 299 | " expr - log expressions\n" |
| 300 | " formatters - log data formatters related activities\n" |
| 301 | " host - log host activities\n" |
| 302 | " jit - log JIT events in the target\n" |
| 303 | " language - log language runtime events\n" |
| 304 | " mmap - log mmap related activities\n" |
| 305 | " module - log module activities such as when modules are created, " |
| 306 | "destroyed, replaced, and more\n" |
| 307 | " object - log object construction/destruction for important objects\n" |
| 308 | " os - log OperatingSystem plugin related activities\n" |
| 309 | " platform - log platform events and activities\n" |
| 310 | " process - log process events and activities\n" |
| 311 | " script - log events about the script interpreter\n" |
| 312 | " state - log private and public process state changes\n" |
| 313 | " step - log step related activities\n" |
| 314 | " symbol - log symbol related issues and warnings\n" |
| 315 | " system-runtime - log system runtime events\n" |
| 316 | " target - log target events and activities\n" |
| 317 | " thread - log thread events and activities\n" |
| 318 | " types - log type system related activities\n" |
| 319 | " unwind - log stack unwind activities\n" |
| 320 | " verbose - enable verbose logging\n" |
| 321 | " watch - log watchpoint related activities\n"); |
Chris Lattner | 30fdc8d | 2010-06-08 16:52:24 +0000 | [diff] [blame] | 322 | } |