blob: 15b861feaa823836949138c3e63541692af3442e [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Jim Ingham40af72e2010-06-15 19:49:27 +000012#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Core/StreamFile.h"
14
15#include "ProcessGDBRemote.h"
16
17using namespace lldb;
18using namespace lldb_private;
19
20
Greg Clayton2d4edfb2010-11-06 01:53:30 +000021// 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.
Greg Clayton5160ce52013-03-27 23:08:40 +000025static bool g_log_enabled = false;
26static Log * g_log = NULL;
27static Log *
Greg Clayton2d4edfb2010-11-06 01:53:30 +000028GetLog ()
29{
Greg Clayton5160ce52013-03-27 23:08:40 +000030 if (!g_log_enabled)
31 return NULL;
32 return g_log;
Greg Clayton2d4edfb2010-11-06 01:53:30 +000033}
34
Greg Clayton5160ce52013-03-27 23:08:40 +000035
36Log *
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask)
38{
Greg Clayton5160ce52013-03-27 23:08:40 +000039 Log *log(GetLog ());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040 if (log && mask)
41 {
Greg Clayton73b472d2010-10-27 03:32:59 +000042 uint32_t log_mask = log->GetMask().Get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043 if ((log_mask & mask) != mask)
Greg Clayton5160ce52013-03-27 23:08:40 +000044 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045 }
46 return log;
47}
48
Greg Clayton5160ce52013-03-27 23:08:40 +000049Log *
Greg Clayton2687cd12012-03-29 01:55:41 +000050ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask)
51{
Greg Clayton5160ce52013-03-27 23:08:40 +000052 Log *log(GetLog ());
Greg Clayton2687cd12012-03-29 01:55:41 +000053 if (log && log->GetMask().Get() & mask)
54 return log;
Greg Clayton5160ce52013-03-27 23:08:40 +000055 return NULL;
Greg Clayton2687cd12012-03-29 01:55:41 +000056}
57
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058void
Jim Ingham228063c2012-02-21 02:23:08 +000059ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm)
Caroline Tice20ad3c42010-10-29 21:48:37 +000060{
Greg Clayton5160ce52013-03-27 23:08:40 +000061 Log *log (GetLog ());
Greg Clayton2d4edfb2010-11-06 01:53:30 +000062 if (log)
Caroline Tice20ad3c42010-10-29 21:48:37 +000063 {
Greg Clayton99d0faf2010-11-18 23:32:35 +000064 uint32_t flag_bits = 0;
65
Jim Ingham228063c2012-02-21 02:23:08 +000066 if (categories[0] != NULL)
Caroline Tice20ad3c42010-10-29 21:48:37 +000067 {
Greg Clayton99d0faf2010-11-18 23:32:35 +000068 flag_bits = log->GetMask().Get();
Jim Ingham228063c2012-02-21 02:23:08 +000069 for (size_t i = 0; categories[i] != NULL; ++i)
Caroline Tice20ad3c42010-10-29 21:48:37 +000070 {
Jim Ingham228063c2012-02-21 02:23:08 +000071 const char *arg = categories[i];
Greg Clayton99d0faf2010-11-18 23:32:35 +000072
73
Greg Clayton05c32e22011-02-04 18:55:41 +000074 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;
Greg Clayton99d0faf2010-11-18 23:32:35 +000088 else
89 {
90 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
91 ListLogCategories (feedback_strm);
92 }
93
Caroline Tice20ad3c42010-10-29 21:48:37 +000094 }
Caroline Tice20ad3c42010-10-29 21:48:37 +000095 }
96
97 if (flag_bits == 0)
Greg Clayton5160ce52013-03-27 23:08:40 +000098 g_log_enabled = false;
Caroline Tice20ad3c42010-10-29 21:48:37 +000099 else
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000100 log->GetMask().Reset (flag_bits);
Caroline Tice20ad3c42010-10-29 21:48:37 +0000101 }
102
103 return;
104}
105
Greg Clayton5160ce52013-03-27 23:08:40 +0000106Log *
Jim Ingham228063c2012-02-21 02:23:08 +0000107ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108{
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000109 // 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.
Greg Clayton1a65ae12011-01-25 23:55:37 +0000111 uint32_t flag_bits = 0;
Greg Clayton5160ce52013-03-27 23:08:40 +0000112 if (g_log)
113 flag_bits = g_log->GetMask().Get();
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000114
115 // Now make a new log with this stream if one was provided
116 if (log_stream_sp)
117 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000118 if (g_log)
119 g_log->SetStream(log_stream_sp);
120 else
121 g_log = new Log(log_stream_sp);
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000122 }
123
Greg Clayton5160ce52013-03-27 23:08:40 +0000124 if (g_log)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 bool got_unknown_category = false;
Jim Ingham228063c2012-02-21 02:23:08 +0000127 for (size_t i=0; categories[i] != NULL; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 {
Jim Ingham228063c2012-02-21 02:23:08 +0000129 const char *arg = categories[i];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130
Greg Clayton05c32e22011-02-04 18:55:41 +0000131 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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 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;
Greg Clayton5160ce52013-03-27 23:08:40 +0000157 g_log->GetMask().Reset(flag_bits);
158 g_log->GetOptions().Reset(log_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 }
Greg Clayton5160ce52013-03-27 23:08:40 +0000160 g_log_enabled = true;
161 return g_log;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162}
163
164void
165ProcessGDBRemoteLog::ListLogCategories (Stream *strm)
166{
Greg Claytonb14eedd2011-09-12 04:05:41 +0000167 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"
Greg Clayton57abc5d2013-05-10 21:47:16 +0000181 " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182}
183
184
185void
186ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...)
187{
Greg Clayton5160ce52013-03-27 23:08:40 +0000188 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189 if (log)
190 {
191 va_list args;
192 va_start (args, format);
193 log->VAPrintf (format, args);
194 va_end (args);
195 }
196}