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