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