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