1 //===-- ProcessKDPLog.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 "ProcessKDPLog.h" 11 12 #include "lldb/Core/StreamFile.h" 13 #include "lldb/Interpreter/Args.h" 14 15 #include "ProcessKDP.h" 16 17 using namespace lldb; 18 using namespace lldb_private; 19 20 // We want to avoid global constructors where code needs to be run so here we 21 // control access to our static g_log_sp by hiding it in a singleton function 22 // that will construct the static g_log_sp the first time this function is 23 // called. 24 static bool g_log_enabled = false; 25 static Log *g_log = NULL; 26 static Log *GetLog() { 27 if (!g_log_enabled) 28 return NULL; 29 return g_log; 30 } 31 32 Log *ProcessKDPLog::GetLogIfAllCategoriesSet(uint32_t mask) { 33 Log *log(GetLog()); 34 if (log && mask) { 35 uint32_t log_mask = log->GetMask().Get(); 36 if ((log_mask & mask) != mask) 37 return NULL; 38 } 39 return log; 40 } 41 42 void ProcessKDPLog::DisableLog(const char **categories, Stream *feedback_strm) { 43 Log *log(GetLog()); 44 if (log) { 45 uint32_t flag_bits = 0; 46 47 if (categories[0] != NULL) { 48 flag_bits = log->GetMask().Get(); 49 for (size_t i = 0; categories[i] != NULL; ++i) { 50 const char *arg = categories[i]; 51 52 if (::strcasecmp(arg, "all") == 0) 53 flag_bits &= ~KDP_LOG_ALL; 54 else if (::strcasecmp(arg, "async") == 0) 55 flag_bits &= ~KDP_LOG_ASYNC; 56 else if (::strncasecmp(arg, "break", 5) == 0) 57 flag_bits &= ~KDP_LOG_BREAKPOINTS; 58 else if (::strncasecmp(arg, "comm", 4) == 0) 59 flag_bits &= ~KDP_LOG_COMM; 60 else if (::strcasecmp(arg, "default") == 0) 61 flag_bits &= ~KDP_LOG_DEFAULT; 62 else if (::strcasecmp(arg, "packets") == 0) 63 flag_bits &= ~KDP_LOG_PACKETS; 64 else if (::strcasecmp(arg, "memory") == 0) 65 flag_bits &= ~KDP_LOG_MEMORY; 66 else if (::strcasecmp(arg, "data-short") == 0) 67 flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT; 68 else if (::strcasecmp(arg, "data-long") == 0) 69 flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG; 70 else if (::strcasecmp(arg, "process") == 0) 71 flag_bits &= ~KDP_LOG_PROCESS; 72 else if (::strcasecmp(arg, "step") == 0) 73 flag_bits &= ~KDP_LOG_STEP; 74 else if (::strcasecmp(arg, "thread") == 0) 75 flag_bits &= ~KDP_LOG_THREAD; 76 else if (::strcasecmp(arg, "verbose") == 0) 77 flag_bits &= ~KDP_LOG_VERBOSE; 78 else if (::strncasecmp(arg, "watch", 5) == 0) 79 flag_bits &= ~KDP_LOG_WATCHPOINTS; 80 else { 81 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 82 ListLogCategories(feedback_strm); 83 } 84 } 85 } 86 87 log->GetMask().Reset(flag_bits); 88 if (flag_bits == 0) 89 g_log_enabled = false; 90 } 91 92 return; 93 } 94 95 Log *ProcessKDPLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, 96 const char **categories, Stream *feedback_strm) { 97 // Try see if there already is a log - that way we can reuse its settings. 98 // We could reuse the log in toto, but we don't know that the stream is the 99 // same. 100 uint32_t flag_bits = 0; 101 if (g_log) 102 flag_bits = g_log->GetMask().Get(); 103 104 // Now make a new log with this stream if one was provided 105 if (log_stream_sp) { 106 if (g_log) 107 g_log->SetStream(log_stream_sp); 108 else 109 g_log = new Log(log_stream_sp); 110 } 111 112 if (g_log) { 113 bool got_unknown_category = false; 114 for (size_t i = 0; categories[i] != NULL; ++i) { 115 const char *arg = categories[i]; 116 117 if (::strcasecmp(arg, "all") == 0) 118 flag_bits |= KDP_LOG_ALL; 119 else if (::strcasecmp(arg, "async") == 0) 120 flag_bits |= KDP_LOG_ASYNC; 121 else if (::strncasecmp(arg, "break", 5) == 0) 122 flag_bits |= KDP_LOG_BREAKPOINTS; 123 else if (::strncasecmp(arg, "comm", 4) == 0) 124 flag_bits |= KDP_LOG_COMM; 125 else if (::strcasecmp(arg, "default") == 0) 126 flag_bits |= KDP_LOG_DEFAULT; 127 else if (::strcasecmp(arg, "packets") == 0) 128 flag_bits |= KDP_LOG_PACKETS; 129 else if (::strcasecmp(arg, "memory") == 0) 130 flag_bits |= KDP_LOG_MEMORY; 131 else if (::strcasecmp(arg, "data-short") == 0) 132 flag_bits |= KDP_LOG_MEMORY_DATA_SHORT; 133 else if (::strcasecmp(arg, "data-long") == 0) 134 flag_bits |= KDP_LOG_MEMORY_DATA_LONG; 135 else if (::strcasecmp(arg, "process") == 0) 136 flag_bits |= KDP_LOG_PROCESS; 137 else if (::strcasecmp(arg, "step") == 0) 138 flag_bits |= KDP_LOG_STEP; 139 else if (::strcasecmp(arg, "thread") == 0) 140 flag_bits |= KDP_LOG_THREAD; 141 else if (::strcasecmp(arg, "verbose") == 0) 142 flag_bits |= KDP_LOG_VERBOSE; 143 else if (::strncasecmp(arg, "watch", 5) == 0) 144 flag_bits |= KDP_LOG_WATCHPOINTS; 145 else { 146 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 147 if (got_unknown_category == false) { 148 got_unknown_category = true; 149 ListLogCategories(feedback_strm); 150 } 151 } 152 } 153 if (flag_bits == 0) 154 flag_bits = KDP_LOG_DEFAULT; 155 g_log->GetMask().Reset(flag_bits); 156 g_log->GetOptions().Reset(log_options); 157 } 158 g_log_enabled = true; 159 return g_log; 160 } 161 162 void ProcessKDPLog::ListLogCategories(Stream *strm) { 163 strm->Printf( 164 "Logging categories for '%s':\n" 165 " all - turn on all available logging categories\n" 166 " async - log asynchronous activity\n" 167 " break - log breakpoints\n" 168 " communication - log communication activity\n" 169 " default - enable the default set of logging categories for liblldb\n" 170 " packets - log gdb remote packets\n" 171 " memory - log memory reads and writes\n" 172 " data-short - log memory bytes for memory reads and writes for short " 173 "transactions only\n" 174 " data-long - log memory bytes for memory reads and writes for all " 175 "transactions\n" 176 " process - log process events and activities\n" 177 " thread - log thread events and activities\n" 178 " step - log step related activities\n" 179 " verbose - enable verbose logging\n" 180 " watch - log watchpoint related activities\n", 181 ProcessKDP::GetPluginNameStatic().GetCString()); 182 } 183 184 void ProcessKDPLog::LogIf(uint32_t mask, const char *format, ...) { 185 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(mask)); 186 if (log) { 187 va_list args; 188 va_start(args, format); 189 log->VAPrintf(format, args); 190 va_end(args); 191 } 192 } 193