blob: 8d415bdc0e777131ab8c2b5a29716b7bb609f1f8 [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
10// C Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include <stdio.h>
12#include <stdarg.h>
13#include <stdlib.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014
15// C++ Includes
16#include <map>
17#include <string>
18
19// Other libraries and framework includes
20// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/Log.h"
22#include "lldb/Core/PluginManager.h"
23#include "lldb/Core/StreamFile.h"
24#include "lldb/Core/StreamString.h"
25#include "lldb/Host/Host.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Host/Mutex.h"
Zachary Turner39de3112014-09-09 20:54:56 +000027#include "lldb/Host/ThisThread.h"
28#include "lldb/Host/TimeValue.h"
Caroline Tice20ad3c42010-10-29 21:48:37 +000029#include "lldb/Interpreter/Args.h"
Zachary Turner50232572015-03-18 21:31:45 +000030#include "lldb/Utility/NameMatches.h"
Zachary Turner39de3112014-09-09 20:54:56 +000031
32#include "llvm/ADT/SmallString.h"
Zachary Turnera893d302015-03-06 20:45:43 +000033#include "llvm/Support/raw_ostream.h"
34#include "llvm/Support/Signals.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035using namespace lldb;
36using namespace lldb_private;
37
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038Log::Log () :
39 m_stream_sp(),
40 m_options(0),
41 m_mask_bits(0)
42{
43}
44
Greg Clayton5160ce52013-03-27 23:08:40 +000045Log::Log (const StreamSP &stream_sp) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 m_stream_sp(stream_sp),
47 m_options(0),
48 m_mask_bits(0)
49{
50}
51
52Log::~Log ()
53{
54}
55
56Flags &
57Log::GetOptions()
58{
59 return m_options;
60}
61
62const Flags &
63Log::GetOptions() const
64{
65 return m_options;
66}
67
68Flags &
69Log::GetMask()
70{
71 return m_mask_bits;
72}
73
74const Flags &
75Log::GetMask() const
76{
77 return m_mask_bits;
78}
79
Zachary Turnerc1592652015-04-29 22:55:28 +000080void
81Log::PutCString(const char *cstr)
82{
83 Printf("%s", cstr);
84}
85
86//----------------------------------------------------------------------
87// Simple variable argument logging with flags.
88//----------------------------------------------------------------------
89void
90Log::Printf(const char *format, ...)
91{
92 va_list args;
93 va_start(args, format);
94 VAPrintf(format, args);
95 va_end(args);
96}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097
98//----------------------------------------------------------------------
99// All logging eventually boils down to this function call. If we have
100// a callback registered, then we call the logging callback. If we have
101// a valid file handle, we also log to the file.
102//----------------------------------------------------------------------
103void
Zachary Turnerc1592652015-04-29 22:55:28 +0000104Log::VAPrintf(const char *format, va_list args)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105{
Greg Claytone98008c2014-02-13 23:34:38 +0000106 // Make a copy of our stream shared pointer in case someone disables our
107 // log while we are logging and releases the stream
108 StreamSP stream_sp(m_stream_sp);
109 if (stream_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 {
111 static uint32_t g_sequence_id = 0;
112 StreamString header;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113
114 // Add a sequence ID if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000115 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116 header.Printf ("%u ", ++g_sequence_id);
117
118 // Timestamp if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000119 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120 {
Virgile Bello0a3b1512013-09-04 13:56:11 +0000121 TimeValue now = TimeValue::Now();
Greg Claytondead71a2015-05-27 16:25:01 +0000122 header.Printf ("%9d.%09.9d ", now.seconds(), now.nanoseconds());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123 }
124
125 // Add the process and thread if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000126 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
Daniel Malead01b2952012-11-29 21:49:15 +0000127 header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128
Ed Mastecc913d142014-05-21 13:46:46 +0000129 // Add the thread name if requested
Greg Clayton73b472d2010-10-27 03:32:59 +0000130 if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131 {
Zachary Turner39de3112014-09-09 20:54:56 +0000132 llvm::SmallString<32> thread_name;
133 ThisThread::GetName(thread_name);
Greg Clayton85719632013-02-27 22:51:58 +0000134 if (!thread_name.empty())
135 header.Printf ("%s ", thread_name.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136 }
137
138 header.PrintfVarArg (format, args);
Zachary Turnera49c5912015-05-08 18:50:54 +0000139 header.PutCString("\n");
140
Zachary Turnera893d302015-03-06 20:45:43 +0000141 if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE))
142 {
143 std::string back_trace;
144 llvm::raw_string_ostream stream(back_trace);
145 llvm::sys::PrintStackTrace(stream);
Todd Fiala53b13702015-10-10 01:26:47 +0000146 stream.flush();
Zachary Turnera49c5912015-05-08 18:50:54 +0000147 header.PutCString(back_trace.c_str());
Zachary Turnera893d302015-03-06 20:45:43 +0000148 }
Zachary Turnera49c5912015-05-08 18:50:54 +0000149
150 if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE))
151 {
152 static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);
153 Mutex::Locker locker(g_LogThreadedMutex);
154 stream_sp->PutCString(header.GetString().c_str());
155 stream_sp->Flush();
156 }
157 else
158 {
159 stream_sp->PutCString(header.GetString().c_str());
160 stream_sp->Flush();
161 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162 }
163}
164
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165//----------------------------------------------------------------------
166// Print debug strings if and only if the global debug option is set to
167// a non-zero value.
168//----------------------------------------------------------------------
169void
Zachary Turnerc1592652015-04-29 22:55:28 +0000170Log::Debug(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171{
Zachary Turnerc1592652015-04-29 22:55:28 +0000172 if (!GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
173 return;
174
175 va_list args;
176 va_start(args, format);
177 VAPrintf(format, args);
178 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179}
180
181
182//----------------------------------------------------------------------
183// Print debug strings if and only if the global debug option is set to
184// a non-zero value.
185//----------------------------------------------------------------------
186void
Zachary Turnerc1592652015-04-29 22:55:28 +0000187Log::DebugVerbose(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188{
Zachary Turnerc1592652015-04-29 22:55:28 +0000189 if (!GetOptions().AllSet(LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
190 return;
191
192 va_list args;
193 va_start(args, format);
194 VAPrintf(format, args);
195 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196}
197
198
199//----------------------------------------------------------------------
200// Log only if all of the bits are set
201//----------------------------------------------------------------------
202void
Zachary Turnerc1592652015-04-29 22:55:28 +0000203Log::LogIf(uint32_t bits, const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204{
Zachary Turnerc1592652015-04-29 22:55:28 +0000205 if (!m_options.AllSet(bits))
206 return;
207
208 va_list args;
209 va_start(args, format);
210 VAPrintf(format, args);
211 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000212}
213
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214//----------------------------------------------------------------------
215// Printing of errors that are not fatal.
216//----------------------------------------------------------------------
217void
Zachary Turnerc1592652015-04-29 22:55:28 +0000218Log::Error(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220 va_list args;
Zachary Turnerc1592652015-04-29 22:55:28 +0000221 va_start(args, format);
Zachary Turner610e5292015-05-07 21:39:33 +0000222 VAError(format, args);
Zachary Turnerc1592652015-04-29 22:55:28 +0000223 va_end(args);
Zachary Turner610e5292015-05-07 21:39:33 +0000224}
225
226
227void
228Log::VAError(const char *format, va_list args)
229{
230 char *arg_msg = nullptr;
231 ::vasprintf(&arg_msg, format, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232
Zachary Turnerc1592652015-04-29 22:55:28 +0000233 if (arg_msg == nullptr)
234 return;
235
Pavel Labathd351bcc2015-04-30 10:47:56 +0000236 Printf("error: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000237 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238}
239
Zachary Turner610e5292015-05-07 21:39:33 +0000240
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241//----------------------------------------------------------------------
242// Printing of errors that ARE fatal. Exit with ERR exit code
243// immediately.
244//----------------------------------------------------------------------
245void
Zachary Turnerc1592652015-04-29 22:55:28 +0000246Log::FatalError(int err, const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247{
Zachary Turnerc1592652015-04-29 22:55:28 +0000248 char *arg_msg = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 va_list args;
Zachary Turnerc1592652015-04-29 22:55:28 +0000250 va_start(args, format);
251 ::vasprintf(&arg_msg, format, args);
252 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253
Zachary Turnerc1592652015-04-29 22:55:28 +0000254 if (arg_msg != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255 {
Zachary Turnerb74e2792015-04-29 23:24:12 +0000256 Printf("error: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000257 ::free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 }
Zachary Turnerc1592652015-04-29 22:55:28 +0000259 ::exit(err);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260}
261
262
263//----------------------------------------------------------------------
264// Printing of warnings that are not fatal only if verbose mode is
265// enabled.
266//----------------------------------------------------------------------
267void
Zachary Turnerc1592652015-04-29 22:55:28 +0000268Log::Verbose(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269{
Zachary Turnerc1592652015-04-29 22:55:28 +0000270 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
271 return;
272
273 va_list args;
274 va_start(args, format);
275 VAPrintf(format, args);
276 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277}
278
279//----------------------------------------------------------------------
280// Printing of warnings that are not fatal only if verbose mode is
281// enabled.
282//----------------------------------------------------------------------
283void
Zachary Turnerc1592652015-04-29 22:55:28 +0000284Log::WarningVerbose(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285{
Zachary Turnerc1592652015-04-29 22:55:28 +0000286 if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
287 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000288
Zachary Turnerc1592652015-04-29 22:55:28 +0000289 char *arg_msg = nullptr;
290 va_list args;
291 va_start(args, format);
292 ::vasprintf(&arg_msg, format, args);
293 va_end(args);
294
295 if (arg_msg == nullptr)
296 return;
297
Zachary Turnerb74e2792015-04-29 23:24:12 +0000298 Printf("warning: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000299 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300}
301//----------------------------------------------------------------------
302// Printing of warnings that are not fatal.
303//----------------------------------------------------------------------
304void
Zachary Turnerc1592652015-04-29 22:55:28 +0000305Log::Warning(const char *format, ...)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306{
Zachary Turnerc1592652015-04-29 22:55:28 +0000307 char *arg_msg = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308 va_list args;
Zachary Turnerc1592652015-04-29 22:55:28 +0000309 va_start(args, format);
310 ::vasprintf(&arg_msg, format, args);
311 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312
Zachary Turnerc1592652015-04-29 22:55:28 +0000313 if (arg_msg == nullptr)
314 return;
315
Zachary Turnerb74e2792015-04-29 23:24:12 +0000316 Printf("warning: %s", arg_msg);
Zachary Turnerc1592652015-04-29 22:55:28 +0000317 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318}
319
Greg Clayton57abc5d2013-05-10 21:47:16 +0000320typedef std::map <ConstString, Log::Callbacks> CallbackMap;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321typedef CallbackMap::iterator CallbackMapIter;
322
323typedef std::map <ConstString, LogChannelSP> LogChannelMap;
324typedef LogChannelMap::iterator LogChannelMapIter;
325
326
327// Surround our callback map with a singleton function so we don't have any
328// global initializers.
329static CallbackMap &
330GetCallbackMap ()
331{
332 static CallbackMap g_callback_map;
333 return g_callback_map;
334}
335
336static LogChannelMap &
337GetChannelMap ()
338{
339 static LogChannelMap g_channel_map;
340 return g_channel_map;
341}
342
343void
Greg Clayton57abc5d2013-05-10 21:47:16 +0000344Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345{
346 GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
347}
348
349bool
Greg Clayton57abc5d2013-05-10 21:47:16 +0000350Log::UnregisterLogChannel (const ConstString &channel)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351{
352 return GetCallbackMap().erase(channel) != 0;
353}
354
355bool
Greg Clayton57abc5d2013-05-10 21:47:16 +0000356Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357{
358 CallbackMap &callback_map = GetCallbackMap ();
359 CallbackMapIter pos = callback_map.find(channel);
360 if (pos != callback_map.end())
361 {
362 log_callbacks = pos->second;
363 return true;
364 }
Greg Clayton72b77eb2011-02-04 21:13:05 +0000365 ::memset (&log_callbacks, 0, sizeof(log_callbacks));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 return false;
367}
368
Tamas Berghammer9c9ecce2015-05-27 13:34:04 +0000369bool
370Log::EnableLogChannel(lldb::StreamSP &log_stream_sp,
371 uint32_t log_options,
372 const char *channel,
373 const char **categories,
374 Stream &error_stream)
375{
376 Log::Callbacks log_callbacks;
377 if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
378 {
379 log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
380 return true;
381 }
382
383 LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
384 if (log_channel_sp)
385 {
386 if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
387 {
388 return true;
389 }
390 else
391 {
392 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
393 return false;
394 }
395 }
396 else
397 {
398 error_stream.Printf ("Invalid log channel '%s'.\n", channel);
399 return false;
400 }
401}
402
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403void
404Log::EnableAllLogChannels
405(
406 StreamSP &log_stream_sp,
407 uint32_t log_options,
Jim Ingham228063c2012-02-21 02:23:08 +0000408 const char **categories,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409 Stream *feedback_strm
410)
411{
412 CallbackMap &callback_map = GetCallbackMap ();
413 CallbackMapIter pos, end = callback_map.end();
414
415 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000416 pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417
418 LogChannelMap &channel_map = GetChannelMap ();
419 LogChannelMapIter channel_pos, channel_end = channel_map.end();
420 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
421 {
Jim Ingham228063c2012-02-21 02:23:08 +0000422 channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423 }
424
425}
426
427void
Greg Claytonab65b342011-04-13 22:47:15 +0000428Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
429{
430 LogChannelMap &map = GetChannelMap ();
431 LogChannelMapIter pos, end = map.end();
432 for (pos = map.begin(); pos != end; ++pos)
433 {
434 const char *pos_channel_name = pos->first.GetCString();
435 if (channel_name && channel_name[0])
436 {
437 if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
438 {
439 matches.AppendString(pos_channel_name);
440 }
441 }
442 else
443 matches.AppendString(pos_channel_name);
444
445 }
446}
447
448void
Caroline Tice20ad3c42010-10-29 21:48:37 +0000449Log::DisableAllLogChannels (Stream *feedback_strm)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450{
451 CallbackMap &callback_map = GetCallbackMap ();
452 CallbackMapIter pos, end = callback_map.end();
Pavel Labathd2c4c9b2015-08-18 08:23:35 +0000453 const char *categories[] = {"all", nullptr};
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454
455 for (pos = callback_map.begin(); pos != end; ++pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000456 pos->second.disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457
458 LogChannelMap &channel_map = GetChannelMap ();
459 LogChannelMapIter channel_pos, channel_end = channel_map.end();
460 for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
Jim Ingham228063c2012-02-21 02:23:08 +0000461 channel_pos->second->Disable (categories, feedback_strm);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462}
463
464void
Greg Clayton99d0faf2010-11-18 23:32:35 +0000465Log::Initialize()
466{
467 Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
Greg Clayton57abc5d2013-05-10 21:47:16 +0000468 Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
Greg Clayton99d0faf2010-11-18 23:32:35 +0000469}
470
471void
472Log::Terminate ()
473{
474 DisableAllLogChannels (NULL);
475}
476
477void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478Log::ListAllLogChannels (Stream *strm)
479{
480 CallbackMap &callback_map = GetCallbackMap ();
481 LogChannelMap &channel_map = GetChannelMap ();
482
483 if (callback_map.empty() && channel_map.empty())
484 {
485 strm->PutCString ("No logging channels are currently registered.\n");
486 return;
487 }
488
489 CallbackMapIter pos, end = callback_map.end();
490 for (pos = callback_map.begin(); pos != end; ++pos)
491 pos->second.list_categories (strm);
492
493 uint32_t idx = 0;
494 const char *name;
495 for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
496 {
497 LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
498 if (log_channel_sp)
499 log_channel_sp->ListCategories (strm);
500 }
501}
502
503bool
504Log::GetVerbose() const
505{
Jim Inghamd8d148e2011-01-22 01:24:30 +0000506 // FIXME: This has to be centralized between the stream and the log...
507 if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
508 return true;
509
Greg Claytone98008c2014-02-13 23:34:38 +0000510 // Make a copy of our stream shared pointer in case someone disables our
511 // log while we are logging and releases the stream
512 StreamSP stream_sp(m_stream_sp);
513 if (stream_sp)
514 return stream_sp->GetVerbose();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000515 return false;
516}
517
518//------------------------------------------------------------------
519// Returns true if the debug flag bit is set in this stream.
520//------------------------------------------------------------------
521bool
522Log::GetDebug() const
523{
Greg Claytone98008c2014-02-13 23:34:38 +0000524 // Make a copy of our stream shared pointer in case someone disables our
525 // log while we are logging and releases the stream
526 StreamSP stream_sp(m_stream_sp);
527 if (stream_sp)
528 return stream_sp->GetDebug();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 return false;
530}
531
532
533LogChannelSP
534LogChannel::FindPlugin (const char *plugin_name)
535{
536 LogChannelSP log_channel_sp;
537 LogChannelMap &channel_map = GetChannelMap ();
538 ConstString log_channel_name (plugin_name);
539 LogChannelMapIter pos = channel_map.find (log_channel_name);
540 if (pos == channel_map.end())
541 {
Greg Clayton57abc5d2013-05-10 21:47:16 +0000542 ConstString const_plugin_name (plugin_name);
543 LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544 if (create_callback)
545 {
546 log_channel_sp.reset(create_callback());
547 if (log_channel_sp)
548 {
549 // Cache the one and only loaded instance of each log channel
550 // plug-in after it has been loaded once.
551 channel_map[log_channel_name] = log_channel_sp;
552 }
553 }
554 }
555 else
556 {
557 // We have already loaded an instance of this log channel class,
558 // so just return the cached instance.
559 log_channel_sp = pos->second;
560 }
561 return log_channel_sp;
562}
563
564LogChannel::LogChannel () :
Greg Clayton5160ce52013-03-27 23:08:40 +0000565 m_log_ap ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566{
567}
568
569LogChannel::~LogChannel ()
570{
571}
572
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000573