blob: 173d954fa16e14f72a900d371e8fba0f3e4a1a9f [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 Turnerc1592652015-04-29 22:55:28 +000054
55//----------------------------------------------------------------------
56// Simple variable argument logging with flags.
57//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000058void Log::Printf(const char *format, ...) {
59 va_list args;
60 va_start(args, format);
61 VAPrintf(format, args);
62 va_end(args);
Zachary Turnerc1592652015-04-29 22:55:28 +000063}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064
65//----------------------------------------------------------------------
66// All logging eventually boils down to this function call. If we have
67// a callback registered, then we call the logging callback. If we have
68// a valid file handle, we also log to the file.
69//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000070void Log::VAPrintf(const char *format, va_list args) {
71 // Make a copy of our stream shared pointer in case someone disables our
72 // log while we are logging and releases the stream
73 StreamSP stream_sp(m_stream_sp);
74 if (stream_sp) {
75 static uint32_t g_sequence_id = 0;
76 StreamString header;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 // Add a sequence ID if requested
79 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_SEQUENCE))
80 header.Printf("%u ", ++g_sequence_id);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 // Timestamp if requested
83 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) {
Pavel Labath774103c2016-11-02 12:18:42 +000084 auto now = std::chrono::duration<double>(
85 std::chrono::system_clock::now().time_since_epoch());
86 header.Printf("%.9f ", now.count());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000088
89 // Add the process and thread if requested
90 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
91 header.Printf("[%4.4x/%4.4" PRIx64 "]: ", getpid(),
92 Host::GetCurrentThreadID());
93
94 // Add the thread name if requested
95 if (m_options.Test(LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) {
96 llvm::SmallString<32> thread_name;
97 ThisThread::GetName(thread_name);
98 if (!thread_name.empty())
99 header.Printf("%s ", thread_name.c_str());
100 }
101
102 header.PrintfVarArg(format, args);
103 header.PutCString("\n");
104
105 if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE)) {
106 std::string back_trace;
107 llvm::raw_string_ostream stream(back_trace);
108 llvm::sys::PrintStackTrace(stream);
109 stream.flush();
110 header.PutCString(back_trace.c_str());
111 }
112
113 if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE)) {
114 static std::recursive_mutex g_LogThreadedMutex;
115 std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex);
116 stream_sp->PutCString(header.GetString().c_str());
117 stream_sp->Flush();
118 } else {
119 stream_sp->PutCString(header.GetString().c_str());
120 stream_sp->Flush();
121 }
122 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123}
124
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000125//----------------------------------------------------------------------
126// Print debug strings if and only if the global debug option is set to
127// a non-zero value.
128//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129void Log::Debug(const char *format, ...) {
130 if (!GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
131 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 va_list args;
134 va_start(args, format);
135 VAPrintf(format, args);
136 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137}
138
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139//----------------------------------------------------------------------
140// Print debug strings if and only if the global debug option is set to
141// a non-zero value.
142//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143void Log::DebugVerbose(const char *format, ...) {
144 if (!GetOptions().AllSet(LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
145 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 va_list args;
148 va_start(args, format);
149 VAPrintf(format, args);
150 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151}
152
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153//----------------------------------------------------------------------
154// Log only if all of the bits are set
155//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156void Log::LogIf(uint32_t bits, const char *format, ...) {
157 if (!m_options.AllSet(bits))
158 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160 va_list args;
161 va_start(args, format);
162 VAPrintf(format, args);
163 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164}
165
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166//----------------------------------------------------------------------
167// Printing of errors that are not fatal.
168//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169void Log::Error(const char *format, ...) {
170 va_list args;
171 va_start(args, format);
172 VAError(format, args);
173 va_end(args);
Zachary Turner610e5292015-05-07 21:39:33 +0000174}
175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176void Log::VAError(const char *format, va_list args) {
177 char *arg_msg = nullptr;
178 ::vasprintf(&arg_msg, format, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 if (arg_msg == nullptr)
181 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 Printf("error: %s", arg_msg);
184 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185}
186
187//----------------------------------------------------------------------
188// Printing of errors that ARE fatal. Exit with ERR exit code
189// immediately.
190//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191void Log::FatalError(int err, const char *format, ...) {
192 char *arg_msg = nullptr;
193 va_list args;
194 va_start(args, format);
195 ::vasprintf(&arg_msg, format, args);
196 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 if (arg_msg != nullptr) {
199 Printf("error: %s", arg_msg);
200 ::free(arg_msg);
201 }
202 ::exit(err);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000203}
204
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205//----------------------------------------------------------------------
206// Printing of warnings that are not fatal only if verbose mode is
207// enabled.
208//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209void Log::Verbose(const char *format, ...) {
210 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
211 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 va_list args;
214 va_start(args, format);
215 VAPrintf(format, args);
216 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217}
218
219//----------------------------------------------------------------------
220// Printing of warnings that are not fatal only if verbose mode is
221// enabled.
222//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223void Log::WarningVerbose(const char *format, ...) {
224 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
225 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226
Kate Stoneb9c1b512016-09-06 20:57:50 +0000227 char *arg_msg = nullptr;
228 va_list args;
229 va_start(args, format);
230 ::vasprintf(&arg_msg, format, args);
231 va_end(args);
Zachary Turnerc1592652015-04-29 22:55:28 +0000232
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 if (arg_msg == nullptr)
234 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000235
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 Printf("warning: %s", arg_msg);
237 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238}
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +0000239
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240//----------------------------------------------------------------------
241// Printing of warnings that are not fatal.
242//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243void Log::Warning(const char *format, ...) {
244 char *arg_msg = nullptr;
245 va_list args;
246 va_start(args, format);
247 ::vasprintf(&arg_msg, format, args);
248 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250 if (arg_msg == nullptr)
251 return;
Zachary Turnerc1592652015-04-29 22:55:28 +0000252
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253 Printf("warning: %s", arg_msg);
254 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255}
256
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257typedef std::map<ConstString, Log::Callbacks> CallbackMap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258typedef CallbackMap::iterator CallbackMapIter;
259
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260typedef std::map<ConstString, LogChannelSP> LogChannelMap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261typedef LogChannelMap::iterator LogChannelMapIter;
262
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263// Surround our callback map with a singleton function so we don't have any
264// global initializers.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265static CallbackMap &GetCallbackMap() {
266 static CallbackMap g_callback_map;
267 return g_callback_map;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268}
269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270static LogChannelMap &GetChannelMap() {
271 static LogChannelMap g_channel_map;
272 return g_channel_map;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000273}
274
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275void Log::RegisterLogChannel(const ConstString &channel,
276 const Log::Callbacks &log_callbacks) {
277 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278}
279
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280bool Log::UnregisterLogChannel(const ConstString &channel) {
281 return GetCallbackMap().erase(channel) != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282}
283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284bool Log::GetLogChannelCallbacks(const ConstString &channel,
285 Log::Callbacks &log_callbacks) {
286 CallbackMap &callback_map = GetCallbackMap();
287 CallbackMapIter pos = callback_map.find(channel);
288 if (pos != callback_map.end()) {
289 log_callbacks = pos->second;
290 return true;
291 }
292 ::memset(&log_callbacks, 0, sizeof(log_callbacks));
293 return false;
294}
295
296bool Log::EnableLogChannel(lldb::StreamSP &log_stream_sp, uint32_t log_options,
297 const char *channel, const char **categories,
298 Stream &error_stream) {
299 Log::Callbacks log_callbacks;
300 if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
301 log_callbacks.enable(log_stream_sp, log_options, categories, &error_stream);
302 return true;
303 }
304
305 LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel));
306 if (log_channel_sp) {
307 if (log_channel_sp->Enable(log_stream_sp, log_options, &error_stream,
308 categories)) {
309 return true;
310 } else {
311 error_stream.Printf("Invalid log channel '%s'.\n", channel);
312 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000314 } else {
315 error_stream.Printf("Invalid log channel '%s'.\n", channel);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318}
319
Kate Stoneb9c1b512016-09-06 20:57:50 +0000320void Log::EnableAllLogChannels(StreamSP &log_stream_sp, uint32_t log_options,
321 const char **categories, Stream *feedback_strm) {
322 CallbackMap &callback_map = GetCallbackMap();
323 CallbackMapIter pos, end = callback_map.end();
324
325 for (pos = callback_map.begin(); pos != end; ++pos)
326 pos->second.enable(log_stream_sp, log_options, categories, feedback_strm);
327
328 LogChannelMap &channel_map = GetChannelMap();
329 LogChannelMapIter channel_pos, channel_end = channel_map.end();
330 for (channel_pos = channel_map.begin(); channel_pos != channel_end;
331 ++channel_pos) {
332 channel_pos->second->Enable(log_stream_sp, log_options, feedback_strm,
333 categories);
334 }
335}
336
337void Log::AutoCompleteChannelName(const char *channel_name,
338 StringList &matches) {
339 LogChannelMap &map = GetChannelMap();
340 LogChannelMapIter pos, end = map.end();
341 for (pos = map.begin(); pos != end; ++pos) {
342 const char *pos_channel_name = pos->first.GetCString();
343 if (channel_name && channel_name[0]) {
344 if (NameMatches(channel_name, eNameMatchStartsWith, pos_channel_name)) {
345 matches.AppendString(pos_channel_name);
346 }
347 } else
348 matches.AppendString(pos_channel_name);
349 }
350}
351
352void Log::DisableAllLogChannels(Stream *feedback_strm) {
353 CallbackMap &callback_map = GetCallbackMap();
354 CallbackMapIter pos, end = callback_map.end();
355 const char *categories[] = {"all", nullptr};
356
357 for (pos = callback_map.begin(); pos != end; ++pos)
358 pos->second.disable(categories, feedback_strm);
359
360 LogChannelMap &channel_map = GetChannelMap();
361 LogChannelMapIter channel_pos, channel_end = channel_map.end();
362 for (channel_pos = channel_map.begin(); channel_pos != channel_end;
363 ++channel_pos)
364 channel_pos->second->Disable(categories, feedback_strm);
365}
366
367void Log::Initialize() {
368 Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
369 Log::RegisterLogChannel(ConstString("lldb"), log_callbacks);
370}
371
372void Log::Terminate() { DisableAllLogChannels(nullptr); }
373
374void Log::ListAllLogChannels(Stream *strm) {
375 CallbackMap &callback_map = GetCallbackMap();
376 LogChannelMap &channel_map = GetChannelMap();
377
378 if (callback_map.empty() && channel_map.empty()) {
379 strm->PutCString("No logging channels are currently registered.\n");
380 return;
381 }
382
383 CallbackMapIter pos, end = callback_map.end();
384 for (pos = callback_map.begin(); pos != end; ++pos)
385 pos->second.list_categories(strm);
386
387 uint32_t idx = 0;
388 const char *name;
389 for (idx = 0;
390 (name = PluginManager::GetLogChannelCreateNameAtIndex(idx)) != nullptr;
391 ++idx) {
392 LogChannelSP log_channel_sp(LogChannel::FindPlugin(name));
Tamas Berghammer9c9ecce2015-05-27 13:34:04 +0000393 if (log_channel_sp)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394 log_channel_sp->ListCategories(strm);
395 }
Tamas Berghammer9c9ecce2015-05-27 13:34:04 +0000396}
397
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398bool Log::GetVerbose() const {
399 // FIXME: This has to be centralized between the stream and the log...
400 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
401 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403 // Make a copy of our stream shared pointer in case someone disables our
404 // log while we are logging and releases the stream
405 StreamSP stream_sp(m_stream_sp);
406 if (stream_sp)
407 return stream_sp->GetVerbose();
408 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409}
410
411//------------------------------------------------------------------
412// Returns true if the debug flag bit is set in this stream.
413//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414bool Log::GetDebug() const {
415 // Make a copy of our stream shared pointer in case someone disables our
416 // log while we are logging and releases the stream
417 StreamSP stream_sp(m_stream_sp);
418 if (stream_sp)
419 return stream_sp->GetDebug();
420 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421}
422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423LogChannelSP LogChannel::FindPlugin(const char *plugin_name) {
424 LogChannelSP log_channel_sp;
425 LogChannelMap &channel_map = GetChannelMap();
426 ConstString log_channel_name(plugin_name);
427 LogChannelMapIter pos = channel_map.find(log_channel_name);
428 if (pos == channel_map.end()) {
429 ConstString const_plugin_name(plugin_name);
430 LogChannelCreateInstance create_callback =
431 PluginManager::GetLogChannelCreateCallbackForPluginName(
432 const_plugin_name);
433 if (create_callback) {
434 log_channel_sp.reset(create_callback());
435 if (log_channel_sp) {
436 // Cache the one and only loaded instance of each log channel
437 // plug-in after it has been loaded once.
438 channel_map[log_channel_name] = log_channel_sp;
439 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 } else {
442 // We have already loaded an instance of this log channel class,
443 // so just return the cached instance.
444 log_channel_sp = pos->second;
445 }
446 return log_channel_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447}
448
Kate Stoneb9c1b512016-09-06 20:57:50 +0000449LogChannel::LogChannel() : m_log_ap() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +0000451LogChannel::~LogChannel() = default;