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