1254721Semaste//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "ProcessPOSIXLog.h" 11254721Semaste 12254721Semaste#include "lldb/Interpreter/Args.h" 13254721Semaste#include "lldb/Core/StreamFile.h" 14254721Semaste 15254721Semaste#include "ProcessPOSIX.h" 16254721Semaste#include "ProcessPOSIXLog.h" 17254721Semaste 18254721Semasteusing namespace lldb; 19254721Semasteusing namespace lldb_private; 20254721Semaste 21254721Semaste 22254721Semaste// We want to avoid global constructors where code needs to be run so here we 23254721Semaste// control access to our static g_log_sp by hiding it in a singleton function 24254721Semaste// that will construct the static g_log_sp the first time this function is 25254721Semaste// called. 26254721Semastestatic bool g_log_enabled = false; 27254721Semastestatic Log * g_log = NULL; 28254721Semastestatic Log * 29254721SemasteGetLog () 30254721Semaste{ 31254721Semaste if (!g_log_enabled) 32254721Semaste return NULL; 33254721Semaste return g_log; 34254721Semaste} 35254721Semaste 36254721Semaste 37254721SemasteLog * 38254721SemasteProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask) 39254721Semaste{ 40254721Semaste Log *log(GetLog ()); 41254721Semaste if (log && mask) 42254721Semaste { 43254721Semaste uint32_t log_mask = log->GetMask().Get(); 44254721Semaste if ((log_mask & mask) != mask) 45254721Semaste return NULL; 46254721Semaste } 47254721Semaste return log; 48254721Semaste} 49254721Semaste 50254721Semastestatic uint32_t 51254721SemasteGetFlagBits (const char *arg) 52254721Semaste{ 53254721Semaste if (::strcasecmp (arg, "all") == 0 ) return POSIX_LOG_ALL; 54254721Semaste else if (::strcasecmp (arg, "async") == 0 ) return POSIX_LOG_ASYNC; 55254721Semaste else if (::strncasecmp (arg, "break", 5) == 0 ) return POSIX_LOG_BREAKPOINTS; 56254721Semaste else if (::strncasecmp (arg, "comm", 4) == 0 ) return POSIX_LOG_COMM; 57254721Semaste else if (::strcasecmp (arg, "default") == 0 ) return POSIX_LOG_DEFAULT; 58254721Semaste else if (::strcasecmp (arg, "packets") == 0 ) return POSIX_LOG_PACKETS; 59254721Semaste else if (::strcasecmp (arg, "memory") == 0 ) return POSIX_LOG_MEMORY; 60254721Semaste else if (::strcasecmp (arg, "data-short") == 0 ) return POSIX_LOG_MEMORY_DATA_SHORT; 61254721Semaste else if (::strcasecmp (arg, "data-long") == 0 ) return POSIX_LOG_MEMORY_DATA_LONG; 62254721Semaste else if (::strcasecmp (arg, "process") == 0 ) return POSIX_LOG_PROCESS; 63254721Semaste else if (::strcasecmp (arg, "ptrace") == 0 ) return POSIX_LOG_PTRACE; 64254721Semaste else if (::strcasecmp (arg, "registers") == 0 ) return POSIX_LOG_REGISTERS; 65254721Semaste else if (::strcasecmp (arg, "step") == 0 ) return POSIX_LOG_STEP; 66254721Semaste else if (::strcasecmp (arg, "thread") == 0 ) return POSIX_LOG_THREAD; 67254721Semaste else if (::strcasecmp (arg, "verbose") == 0 ) return POSIX_LOG_VERBOSE; 68254721Semaste else if (::strncasecmp (arg, "watch", 5) == 0 ) return POSIX_LOG_WATCHPOINTS; 69254721Semaste return 0; 70254721Semaste} 71254721Semaste 72254721Semastevoid 73254721SemasteProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm) 74254721Semaste{ 75254721Semaste Log *log (GetLog ()); 76254721Semaste if (log) 77254721Semaste { 78254721Semaste uint32_t flag_bits = 0; 79254721Semaste 80254721Semaste flag_bits = log->GetMask().Get(); 81254721Semaste for (; args[0]; args++) 82254721Semaste { 83254721Semaste const char *arg = args[0]; 84254721Semaste uint32_t bits = GetFlagBits(arg); 85254721Semaste 86254721Semaste if (bits) 87254721Semaste { 88254721Semaste flag_bits &= ~bits; 89254721Semaste } 90254721Semaste else 91254721Semaste { 92254721Semaste feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 93254721Semaste ListLogCategories (feedback_strm); 94254721Semaste } 95254721Semaste } 96254721Semaste 97254721Semaste log->GetMask().Reset (flag_bits); 98254721Semaste if (flag_bits == 0) 99254721Semaste g_log_enabled = false; 100254721Semaste } 101254721Semaste 102254721Semaste return; 103254721Semaste} 104254721Semaste 105254721SemasteLog * 106254721SemasteProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm) 107254721Semaste{ 108254721Semaste // Try see if there already is a log - that way we can reuse its settings. 109254721Semaste // We could reuse the log in toto, but we don't know that the stream is the same. 110254721Semaste uint32_t flag_bits = 0; 111254721Semaste if (g_log) 112254721Semaste flag_bits = g_log->GetMask().Get(); 113254721Semaste 114254721Semaste // Now make a new log with this stream if one was provided 115254721Semaste if (log_stream_sp) 116254721Semaste { 117254721Semaste if (g_log) 118254721Semaste g_log->SetStream(log_stream_sp); 119254721Semaste else 120254721Semaste g_log = new Log(log_stream_sp); 121254721Semaste } 122254721Semaste 123254721Semaste if (g_log) 124254721Semaste { 125254721Semaste bool got_unknown_category = false; 126254721Semaste for (; args[0]; args++) 127254721Semaste { 128254721Semaste const char *arg = args[0]; 129254721Semaste uint32_t bits = GetFlagBits(arg); 130254721Semaste 131254721Semaste if (bits) 132254721Semaste { 133254721Semaste flag_bits |= bits; 134254721Semaste } 135254721Semaste else 136254721Semaste { 137254721Semaste feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); 138254721Semaste if (got_unknown_category == false) 139254721Semaste { 140254721Semaste got_unknown_category = true; 141254721Semaste ListLogCategories (feedback_strm); 142254721Semaste } 143254721Semaste } 144254721Semaste } 145254721Semaste if (flag_bits == 0) 146254721Semaste flag_bits = POSIX_LOG_DEFAULT; 147254721Semaste g_log->GetMask().Reset(flag_bits); 148254721Semaste g_log->GetOptions().Reset(log_options); 149254721Semaste g_log_enabled = true; 150254721Semaste } 151254721Semaste return g_log; 152254721Semaste} 153254721Semaste 154254721Semastevoid 155254721SemasteProcessPOSIXLog::ListLogCategories (Stream *strm) 156254721Semaste{ 157254721Semaste strm->Printf ("Logging categories for '%s':\n" 158254721Semaste " all - turn on all available logging categories\n" 159254721Semaste " async - log asynchronous activity\n" 160254721Semaste " break - log breakpoints\n" 161254721Semaste " communication - log communication activity\n" 162254721Semaste " default - enable the default set of logging categories for liblldb\n" 163254721Semaste " packets - log gdb remote packets\n" 164254721Semaste " memory - log memory reads and writes\n" 165254721Semaste " data-short - log memory bytes for memory reads and writes for short transactions only\n" 166254721Semaste " data-long - log memory bytes for memory reads and writes for all transactions\n" 167254721Semaste " process - log process events and activities\n" 168254721Semaste#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION 169254721Semaste " ptrace - log all calls to ptrace\n" 170254721Semaste#endif 171254721Semaste " registers - log register read/writes\n" 172254721Semaste " thread - log thread events and activities\n" 173254721Semaste " step - log step related activities\n" 174254721Semaste " verbose - enable verbose logging\n" 175254721Semaste " watch - log watchpoint related activities\n", ProcessPOSIXLog::m_pluginname); 176254721Semaste} 177254721Semaste 178254721Semaste 179254721Semastevoid 180254721SemasteProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...) 181254721Semaste{ 182254721Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask)); 183254721Semaste if (log) 184254721Semaste { 185254721Semaste va_list args; 186254721Semaste va_start (args, format); 187254721Semaste log->VAPrintf (format, args); 188254721Semaste va_end (args); 189254721Semaste } 190254721Semaste} 191254721Semaste 192254721Semasteint ProcessPOSIXLog::m_nestinglevel; 193254721Semasteconst char *ProcessPOSIXLog::m_pluginname = ""; 194