blob: d4726adc890efa3abde962dcade7122951ef7aca [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
Robert Flack5f4b6c72015-03-11 21:14:22 +000012#include <mutex>
13
Jim Ingham40af72e2010-06-15 19:49:27 +000014#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Core/StreamFile.h"
16
17#include "ProcessGDBRemote.h"
18
19using namespace lldb;
20using namespace lldb_private;
Tamas Berghammerdb264a62015-03-31 09:52:22 +000021using namespace lldb_private::process_gdb_remote;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
23
Greg Clayton2d4edfb2010-11-06 01:53:30 +000024// We want to avoid global constructors where code needs to be run so here we
25// control access to our static g_log_sp by hiding it in a singleton function
26// that will construct the static g_lob_sp the first time this function is
27// called.
Greg Clayton5160ce52013-03-27 23:08:40 +000028static bool g_log_enabled = false;
29static Log * g_log = NULL;
30static Log *
Greg Clayton2d4edfb2010-11-06 01:53:30 +000031GetLog ()
32{
Greg Clayton5160ce52013-03-27 23:08:40 +000033 if (!g_log_enabled)
34 return NULL;
35 return g_log;
Greg Clayton2d4edfb2010-11-06 01:53:30 +000036}
37
Robert Flack5f4b6c72015-03-11 21:14:22 +000038void
39ProcessGDBRemoteLog::Initialize()
40{
41 static ConstString g_name("gdb-remote");
42 static std::once_flag g_once_flag;
43
44 std::call_once(g_once_flag, [](){
45 Log::Callbacks log_callbacks = {
46 DisableLog,
47 EnableLog,
48 ListLogCategories
49 };
50
51 Log::RegisterLogChannel (g_name, log_callbacks);
52 });
53}
Greg Clayton5160ce52013-03-27 23:08:40 +000054
55Log *
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask)
57{
Greg Clayton5160ce52013-03-27 23:08:40 +000058 Log *log(GetLog ());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059 if (log && mask)
60 {
Greg Clayton73b472d2010-10-27 03:32:59 +000061 uint32_t log_mask = log->GetMask().Get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062 if ((log_mask & mask) != mask)
Greg Clayton5160ce52013-03-27 23:08:40 +000063 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064 }
65 return log;
66}
67
Greg Clayton5160ce52013-03-27 23:08:40 +000068Log *
Greg Clayton2687cd12012-03-29 01:55:41 +000069ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask)
70{
Greg Clayton5160ce52013-03-27 23:08:40 +000071 Log *log(GetLog ());
Greg Clayton2687cd12012-03-29 01:55:41 +000072 if (log && log->GetMask().Get() & mask)
73 return log;
Greg Clayton5160ce52013-03-27 23:08:40 +000074 return NULL;
Greg Clayton2687cd12012-03-29 01:55:41 +000075}
76
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077void
Jim Ingham228063c2012-02-21 02:23:08 +000078ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm)
Caroline Tice20ad3c42010-10-29 21:48:37 +000079{
Greg Clayton5160ce52013-03-27 23:08:40 +000080 Log *log (GetLog ());
Greg Clayton2d4edfb2010-11-06 01:53:30 +000081 if (log)
Caroline Tice20ad3c42010-10-29 21:48:37 +000082 {
Greg Clayton99d0faf2010-11-18 23:32:35 +000083 uint32_t flag_bits = 0;
84
Jim Ingham228063c2012-02-21 02:23:08 +000085 if (categories[0] != NULL)
Caroline Tice20ad3c42010-10-29 21:48:37 +000086 {
Greg Clayton99d0faf2010-11-18 23:32:35 +000087 flag_bits = log->GetMask().Get();
Jim Ingham228063c2012-02-21 02:23:08 +000088 for (size_t i = 0; categories[i] != NULL; ++i)
Caroline Tice20ad3c42010-10-29 21:48:37 +000089 {
Jim Ingham228063c2012-02-21 02:23:08 +000090 const char *arg = categories[i];
Greg Clayton99d0faf2010-11-18 23:32:35 +000091
92
Greg Clayton05c32e22011-02-04 18:55:41 +000093 if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~GDBR_LOG_ALL;
94 else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~GDBR_LOG_ASYNC;
95 else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~GDBR_LOG_BREAKPOINTS;
96 else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~GDBR_LOG_COMM;
97 else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~GDBR_LOG_DEFAULT;
98 else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~GDBR_LOG_PACKETS;
99 else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY;
100 else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
101 else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
102 else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~GDBR_LOG_PROCESS;
103 else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~GDBR_LOG_STEP;
104 else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~GDBR_LOG_THREAD;
105 else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~GDBR_LOG_VERBOSE;
106 else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~GDBR_LOG_WATCHPOINTS;
Greg Clayton99d0faf2010-11-18 23:32:35 +0000107 else
108 {
109 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
110 ListLogCategories (feedback_strm);
111 }
112
Caroline Tice20ad3c42010-10-29 21:48:37 +0000113 }
Caroline Tice20ad3c42010-10-29 21:48:37 +0000114 }
115
116 if (flag_bits == 0)
Greg Clayton5160ce52013-03-27 23:08:40 +0000117 g_log_enabled = false;
Caroline Tice20ad3c42010-10-29 21:48:37 +0000118 else
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000119 log->GetMask().Reset (flag_bits);
Caroline Tice20ad3c42010-10-29 21:48:37 +0000120 }
121
122 return;
123}
124
Greg Clayton5160ce52013-03-27 23:08:40 +0000125Log *
Jim Ingham228063c2012-02-21 02:23:08 +0000126ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127{
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000128 // Try see if there already is a log - that way we can reuse its settings.
129 // 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 +0000130 uint32_t flag_bits = 0;
Greg Clayton5160ce52013-03-27 23:08:40 +0000131 if (g_log)
132 flag_bits = g_log->GetMask().Get();
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000133
134 // Now make a new log with this stream if one was provided
135 if (log_stream_sp)
136 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000137 if (g_log)
138 g_log->SetStream(log_stream_sp);
139 else
140 g_log = new Log(log_stream_sp);
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000141 }
142
Greg Clayton5160ce52013-03-27 23:08:40 +0000143 if (g_log)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 bool got_unknown_category = false;
Jim Ingham228063c2012-02-21 02:23:08 +0000146 for (size_t i=0; categories[i] != NULL; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 {
Jim Ingham228063c2012-02-21 02:23:08 +0000148 const char *arg = categories[i];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149
Greg Clayton05c32e22011-02-04 18:55:41 +0000150 if (::strcasecmp (arg, "all") == 0 ) flag_bits |= GDBR_LOG_ALL;
151 else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= GDBR_LOG_ASYNC;
152 else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= GDBR_LOG_BREAKPOINTS;
153 else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= GDBR_LOG_COMM;
154 else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= GDBR_LOG_DEFAULT;
155 else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= GDBR_LOG_PACKETS;
156 else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= GDBR_LOG_MEMORY;
157 else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT;
158 else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_LONG;
159 else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= GDBR_LOG_PROCESS;
160 else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= GDBR_LOG_STEP;
161 else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= GDBR_LOG_THREAD;
162 else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= GDBR_LOG_VERBOSE;
163 else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= GDBR_LOG_WATCHPOINTS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164 else
165 {
166 feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
167 if (got_unknown_category == false)
168 {
169 got_unknown_category = true;
170 ListLogCategories (feedback_strm);
171 }
172 }
173 }
174 if (flag_bits == 0)
175 flag_bits = GDBR_LOG_DEFAULT;
Greg Clayton5160ce52013-03-27 23:08:40 +0000176 g_log->GetMask().Reset(flag_bits);
177 g_log->GetOptions().Reset(log_options);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 }
Greg Clayton5160ce52013-03-27 23:08:40 +0000179 g_log_enabled = true;
180 return g_log;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181}
182
183void
184ProcessGDBRemoteLog::ListLogCategories (Stream *strm)
185{
Greg Claytonb14eedd2011-09-12 04:05:41 +0000186 strm->Printf ("Logging categories for '%s':\n"
187 " all - turn on all available logging categories\n"
188 " async - log asynchronous activity\n"
189 " break - log breakpoints\n"
190 " communication - log communication activity\n"
191 " default - enable the default set of logging categories for liblldb\n"
192 " packets - log gdb remote packets\n"
193 " memory - log memory reads and writes\n"
194 " data-short - log memory bytes for memory reads and writes for short transactions only\n"
195 " data-long - log memory bytes for memory reads and writes for all transactions\n"
196 " process - log process events and activities\n"
197 " thread - log thread events and activities\n"
198 " step - log step related activities\n"
199 " verbose - enable verbose logging\n"
Greg Clayton57abc5d2013-05-10 21:47:16 +0000200 " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201}
202
203
204void
205ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...)
206{
Greg Clayton5160ce52013-03-27 23:08:40 +0000207 Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208 if (log)
209 {
210 va_list args;
211 va_start (args, format);
212 log->VAPrintf (format, args);
213 va_end (args);
214 }
215}