blob: 53195006b3b4cb824dcf4e3109c6048763b0cf53 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Log.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
Pavel Labath774103c2016-11-02 12:18:42 +000010// Project includes
11#include "lldb/Core/Log.h"
12#include "lldb/Core/PluginManager.h"
13#include "lldb/Core/StreamFile.h"
14#include "lldb/Core/StreamString.h"
15#include "lldb/Host/Host.h"
16#include "lldb/Host/ThisThread.h"
17#include "lldb/Interpreter/Args.h"
18#include "lldb/Utility/NameMatches.h"
19
20// Other libraries and framework includes
21#include "llvm/ADT/SmallString.h"
22#include "llvm/Support/Chrono.h"
23#include "llvm/Support/Signals.h"
24#include "llvm/Support/raw_ostream.h"
25
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026// C Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027// C++ Includes
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000028#include <cstdarg>
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000029#include <cstdio>
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000030#include <cstdlib>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include <map>
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000032#include <mutex>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include <string>
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035using namespace lldb;
36using namespace lldb_private;
37
Kate Stoneb9c1b512016-09-06 20:57:50 +000038Log::Log() : m_stream_sp(), m_options(0), m_mask_bits(0) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040Log::Log(const StreamSP &stream_sp)
41 : m_stream_sp(stream_sp), m_options(0), m_mask_bits(0) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000043Log::~Log() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
Kate Stoneb9c1b512016-09-06 20:57:50 +000045Flags &Log::GetOptions() { return m_options; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046
Kate Stoneb9c1b512016-09-06 20:57:50 +000047const Flags &Log::GetOptions() const { return m_options; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049Flags &Log::GetMask() { return m_mask_bits; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051const Flags &Log::GetMask() const { return m_mask_bits; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053void Log::PutCString(const char *cstr) { Printf("%s", cstr); }
Zachary Turnerc1564272016-11-16 21:15:24 +000054void Log::PutString(llvm::StringRef str) { PutCString(str.str().c_str()); }
Zachary Turnerc1592652015-04-29 22:55:28 +000055
56//----------------------------------------------------------------------
57// Simple variable argument logging with flags.
58//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000059void Log::Printf(const char *format, ...) {
60 va_list args;
61 va_start(args, format);
62 VAPrintf(format, args);
63 va_end(args);
Zachary Turnerc1592652015-04-29 22:55:28 +000064}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065
66//----------------------------------------------------------------------
67// All logging eventually boils down to this function call. If we have
68// a callback registered, then we call the logging callback. If we have
69// a valid file handle, we also log to the file.
70//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000071void Log::VAPrintf(const char *format, va_list args) {
72 // Make a copy of our stream shared pointer in case someone disables our
73 // log while we are logging and releases the stream
74 StreamSP stream_sp(m_stream_sp);
75 if (stream_sp) {
76 static uint32_t g_sequence_id = 0;
77 StreamString header;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 // Add a sequence ID if requested
80 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_SEQUENCE))
81 header.Printf("%u ", ++g_sequence_id);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 // Timestamp if requested
84 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) {
Pavel Labath774103c2016-11-02 12:18:42 +000085 auto now = std::chrono::duration<double>(
86 std::chrono::system_clock::now().time_since_epoch());
87 header.Printf("%.9f ", now.count());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000089
90 // Add the process and thread if requested
91 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
92 header.Printf("[%4.4x/%4.4" PRIx64 "]: ", getpid(),
93 Host::GetCurrentThreadID());
94
95 // Add the thread name if requested
96 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) {
97 llvm::SmallString<32> thread_name;
98 ThisThread::GetName(thread_name);
99 if (!thread_name.empty())
100 header.Printf("%s ", thread_name.c_str());
101 }
102
103 header.PrintfVarArg(format, args);
104 header.PutCString("\n");
105
106 if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE)) {
107 std::string back_trace;
108 llvm::raw_string_ostream stream(back_trace);
109 llvm::sys::PrintStackTrace(stream);
110 stream.flush();
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000111 header.PutCString(back_trace);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112 }
113
114 if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE)) {
115 static std::recursive_mutex g_LogThreadedMutex;
116 std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex);
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000117 stream_sp->PutCString(header.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118 stream_sp->Flush();
119 } else {
Malcolm Parsons771ef6d2016-11-02 20:34:10 +0000120 stream_sp->PutCString(header.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 stream_sp->Flush();
122 }
123 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124}
125
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126//----------------------------------------------------------------------
127// Print debug strings if and only if the global debug option is set to
128// a non-zero value.
129//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130void Log::Debug(const char *format, ...) {
131 if (!GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
132 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 va_list args;
135 va_start(args, format);
136 VAPrintf(format, args);
137 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000138}
139
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140//----------------------------------------------------------------------
141// Print debug strings if and only if the global debug option is set to
142// a non-zero value.
143//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144void Log::DebugVerbose(const char *format, ...) {
145 if (!GetOptions().AllSet(LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
146 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 va_list args;
149 va_start(args, format);
150 VAPrintf(format, args);
151 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152}
153
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154//----------------------------------------------------------------------
155// Log only if all of the bits are set
156//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157void Log::LogIf(uint32_t bits, const char *format, ...) {
158 if (!m_options.AllSet(bits))
159 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 va_list args;
162 va_start(args, format);
163 VAPrintf(format, args);
164 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165}
166
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167//----------------------------------------------------------------------
168// Printing of errors that are not fatal.
169//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170void Log::Error(const char *format, ...) {
171 va_list args;
172 va_start(args, format);
173 VAError(format, args);
174 va_end(args);
Zachary Turner610e5292015-05-07 21:39:33 +0000175}
176
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177void Log::VAError(const char *format, va_list args) {
178 char *arg_msg = nullptr;
179 ::vasprintf(&arg_msg, format, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 if (arg_msg == nullptr)
182 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184 Printf("error: %s", arg_msg);
185 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186}
187
188//----------------------------------------------------------------------
189// Printing of errors that ARE fatal. Exit with ERR exit code
190// immediately.
191//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192void Log::FatalError(int err, const char *format, ...) {
193 char *arg_msg = nullptr;
194 va_list args;
195 va_start(args, format);
196 ::vasprintf(&arg_msg, format, args);
197 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199 if (arg_msg != nullptr) {
200 Printf("error: %s", arg_msg);
201 ::free(arg_msg);
202 }
203 ::exit(err);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204}
205
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206//----------------------------------------------------------------------
207// Printing of warnings that are not fatal only if verbose mode is
208// enabled.
209//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210void Log::Verbose(const char *format, ...) {
211 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
212 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000213
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 va_list args;
215 va_start(args, format);
216 VAPrintf(format, args);
217 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218}
219
220//----------------------------------------------------------------------
221// Printing of warnings that are not fatal only if verbose mode is
222// enabled.
223//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000224void Log::WarningVerbose(const char *format, ...) {
225 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
226 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 char *arg_msg = nullptr;
229 va_list args;
230 va_start(args, format);
231 ::vasprintf(&arg_msg, format, args);
232 va_end(args);
Zachary Turnerc1592652015-04-29 22:55:28 +0000233
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234 if (arg_msg == nullptr)
235 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000236
Kate Stoneb9c1b512016-09-06 20:57:50 +0000237 Printf("warning: %s", arg_msg);
238 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239}
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +0000240
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241//----------------------------------------------------------------------
242// Printing of warnings that are not fatal.
243//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244void Log::Warning(const char *format, ...) {
245 char *arg_msg = nullptr;
246 va_list args;
247 va_start(args, format);
248 ::vasprintf(&arg_msg, format, args);
249 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 if (arg_msg == nullptr)
252 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000253
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 Printf("warning: %s", arg_msg);
255 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256}
257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258typedef std::map<ConstString, Log::Callbacks> CallbackMap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259typedef CallbackMap::iterator CallbackMapIter;
260
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261typedef std::map<ConstString, LogChannelSP> LogChannelMap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262typedef LogChannelMap::iterator LogChannelMapIter;
263
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264// Surround our callback map with a singleton function so we don't have any
265// global initializers.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266static CallbackMap &GetCallbackMap() {
267 static CallbackMap g_callback_map;
268 return g_callback_map;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269}
270
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271static LogChannelMap &GetChannelMap() {
272 static LogChannelMap g_channel_map;
273 return g_channel_map;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274}
275
Kate Stoneb9c1b512016-09-06 20:57:50 +0000276void Log::RegisterLogChannel(const ConstString &channel,
277 const Log::Callbacks &log_callbacks) {
278 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279}
280
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281bool Log::UnregisterLogChannel(const ConstString &channel) {
282 return GetCallbackMap().erase(channel) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283}
284
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285bool Log::GetLogChannelCallbacks(const ConstString &channel,
286 Log::Callbacks &log_callbacks) {
287 CallbackMap &callback_map = GetCallbackMap();
288 CallbackMapIter pos = callback_map.find(channel);
289 if (pos != callback_map.end()) {
290 log_callbacks = pos->second;
291 return true;
292 }
293 ::memset(&log_callbacks, 0, sizeof(log_callbacks));
294 return false;
295}
296
297bool Log::EnableLogChannel(lldb::StreamSP &log_stream_sp, uint32_t log_options,
298 const char *channel, const char **categories,
299 Stream &error_stream) {
300 Log::Callbacks log_callbacks;
301 if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
302 log_callbacks.enable(log_stream_sp, log_options, categories, &error_stream);
303 return true;
304 }
305
306 LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel));
307 if (log_channel_sp) {
308 if (log_channel_sp->Enable(log_stream_sp, log_options, &error_stream,
309 categories)) {
310 return true;
311 } else {
312 error_stream.Printf("Invalid log channel '%s'.\n", channel);
313 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315 } else {
316 error_stream.Printf("Invalid log channel '%s'.\n", channel);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319}
320
Kate Stoneb9c1b512016-09-06 20:57:50 +0000321void Log::EnableAllLogChannels(StreamSP &log_stream_sp, uint32_t log_options,
322 const char **categories, Stream *feedback_strm) {
323 CallbackMap &callback_map = GetCallbackMap();
324 CallbackMapIter pos, end = callback_map.end();
325
326 for (pos = callback_map.begin(); pos != end; ++pos)
327 pos->second.enable(log_stream_sp, log_options, categories, feedback_strm);
328
329 LogChannelMap &channel_map = GetChannelMap();
330 LogChannelMapIter channel_pos, channel_end = channel_map.end();
331 for (channel_pos = channel_map.begin(); channel_pos != channel_end;
332 ++channel_pos) {
333 channel_pos->second->Enable(log_stream_sp, log_options, feedback_strm,
334 categories);
335 }
336}
337
338void Log::AutoCompleteChannelName(const char *channel_name,
339 StringList &matches) {
340 LogChannelMap &map = GetChannelMap();
341 LogChannelMapIter pos, end = map.end();
342 for (pos = map.begin(); pos != end; ++pos) {
343 const char *pos_channel_name = pos->first.GetCString();
344 if (channel_name && channel_name[0]) {
345 if (NameMatches(channel_name, eNameMatchStartsWith, pos_channel_name)) {
346 matches.AppendString(pos_channel_name);
347 }
348 } else
349 matches.AppendString(pos_channel_name);
350 }
351}
352
353void Log::DisableAllLogChannels(Stream *feedback_strm) {
354 CallbackMap &callback_map = GetCallbackMap();
355 CallbackMapIter pos, end = callback_map.end();
356 const char *categories[] = {"all", nullptr};
357
358 for (pos = callback_map.begin(); pos != end; ++pos)
359 pos->second.disable(categories, feedback_strm);
360
361 LogChannelMap &channel_map = GetChannelMap();
362 LogChannelMapIter channel_pos, channel_end = channel_map.end();
363 for (channel_pos = channel_map.begin(); channel_pos != channel_end;
364 ++channel_pos)
365 channel_pos->second->Disable(categories, feedback_strm);
366}
367
368void Log::Initialize() {
369 Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
370 Log::RegisterLogChannel(ConstString("lldb"), log_callbacks);
371}
372
373void Log::Terminate() { DisableAllLogChannels(nullptr); }
374
375void Log::ListAllLogChannels(Stream *strm) {
376 CallbackMap &callback_map = GetCallbackMap();
377 LogChannelMap &channel_map = GetChannelMap();
378
379 if (callback_map.empty() && channel_map.empty()) {
380 strm->PutCString("No logging channels are currently registered.\n");
381 return;
382 }
383
384 CallbackMapIter pos, end = callback_map.end();
385 for (pos = callback_map.begin(); pos != end; ++pos)
386 pos->second.list_categories(strm);
387
388 uint32_t idx = 0;
389 const char *name;
390 for (idx = 0;
391 (name = PluginManager::GetLogChannelCreateNameAtIndex(idx)) != nullptr;
392 ++idx) {
393 LogChannelSP log_channel_sp(LogChannel::FindPlugin(name));
Tamas Berghammer9c9ecce2015-05-27 13:34:04 +0000394 if (log_channel_sp)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395 log_channel_sp->ListCategories(strm);
396 }
Tamas Berghammer9c9ecce2015-05-27 13:34:04 +0000397}
398
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399bool Log::GetVerbose() const {
400 // FIXME: This has to be centralized between the stream and the log...
401 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
402 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404 // Make a copy of our stream shared pointer in case someone disables our
405 // log while we are logging and releases the stream
406 StreamSP stream_sp(m_stream_sp);
407 if (stream_sp)
408 return stream_sp->GetVerbose();
409 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410}
411
412//------------------------------------------------------------------
413// Returns true if the debug flag bit is set in this stream.
414//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415bool Log::GetDebug() const {
416 // Make a copy of our stream shared pointer in case someone disables our
417 // log while we are logging and releases the stream
418 StreamSP stream_sp(m_stream_sp);
419 if (stream_sp)
420 return stream_sp->GetDebug();
421 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422}
423
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424LogChannelSP LogChannel::FindPlugin(const char *plugin_name) {
425 LogChannelSP log_channel_sp;
426 LogChannelMap &channel_map = GetChannelMap();
427 ConstString log_channel_name(plugin_name);
428 LogChannelMapIter pos = channel_map.find(log_channel_name);
429 if (pos == channel_map.end()) {
430 ConstString const_plugin_name(plugin_name);
431 LogChannelCreateInstance create_callback =
432 PluginManager::GetLogChannelCreateCallbackForPluginName(
433 const_plugin_name);
434 if (create_callback) {
435 log_channel_sp.reset(create_callback());
436 if (log_channel_sp) {
437 // Cache the one and only loaded instance of each log channel
438 // plug-in after it has been loaded once.
439 channel_map[log_channel_name] = log_channel_sp;
440 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 } else {
443 // We have already loaded an instance of this log channel class,
444 // so just return the cached instance.
445 log_channel_sp = pos->second;
446 }
447 return log_channel_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448}
449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450LogChannel::LogChannel() : m_log_ap() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +0000452LogChannel::~LogChannel() = default;