1//===-- 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#include "lldb/lldb-python.h"
11
12// C Includes
13#include <pthread.h>
14#include <stdio.h>
15#include <stdarg.h>
16#include <stdlib.h>
17#include <unistd.h>
18
19// C++ Includes
20#include <map>
21#include <string>
22
23// Other libraries and framework includes
24// Project includes
25#include "lldb/Core/Debugger.h"
26#include "lldb/Core/Log.h"
27#include "lldb/Core/PluginManager.h"
28#include "lldb/Core/StreamFile.h"
29#include "lldb/Core/StreamString.h"
30#include "lldb/Host/Host.h"
31#include "lldb/Host/TimeValue.h"
32#include "lldb/Host/Mutex.h"
33#include "lldb/Interpreter/Args.h"
34using namespace lldb;
35using namespace lldb_private;
36
37Log::Log () :
38    m_stream_sp(),
39    m_options(0),
40    m_mask_bits(0)
41{
42}
43
44Log::Log (const StreamSP &stream_sp) :
45    m_stream_sp(stream_sp),
46    m_options(0),
47    m_mask_bits(0)
48{
49}
50
51Log::~Log ()
52{
53}
54
55Flags &
56Log::GetOptions()
57{
58    return m_options;
59}
60
61const Flags &
62Log::GetOptions() const
63{
64    return m_options;
65}
66
67Flags &
68Log::GetMask()
69{
70    return m_mask_bits;
71}
72
73const Flags &
74Log::GetMask() const
75{
76    return m_mask_bits;
77}
78
79
80//----------------------------------------------------------------------
81// All logging eventually boils down to this function call. If we have
82// a callback registered, then we call the logging callback. If we have
83// a valid file handle, we also log to the file.
84//----------------------------------------------------------------------
85void
86Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args)
87{
88    if (m_stream_sp)
89    {
90        static uint32_t g_sequence_id = 0;
91        StreamString header;
92		// Enabling the thread safe logging actually deadlocks right now.
93		// Need to fix this at some point.
94//        static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);
95//        Mutex::Locker locker (g_LogThreadedMutex);
96
97        // Add a sequence ID if requested
98        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
99            header.Printf ("%u ", ++g_sequence_id);
100
101        // Timestamp if requested
102        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
103        {
104            struct timeval tv = TimeValue::Now().GetAsTimeVal();
105            header.Printf ("%9ld.%6.6d ", tv.tv_sec, (int32_t)tv.tv_usec);
106        }
107
108        // Add the process and thread if requested
109        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
110            header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
111
112        // Add the process and thread if requested
113        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
114        {
115            std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID()));
116            if (!thread_name.empty())
117                header.Printf ("%s ", thread_name.c_str());
118        }
119
120        header.PrintfVarArg (format, args);
121        m_stream_sp->Printf("%s\n", header.GetData());
122
123        if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE))
124            Host::Backtrace (*m_stream_sp, 1024);
125        m_stream_sp->Flush();
126    }
127}
128
129
130void
131Log::PutCString (const char *cstr)
132{
133    Printf ("%s", cstr);
134}
135
136
137//----------------------------------------------------------------------
138// Simple variable argument logging with flags.
139//----------------------------------------------------------------------
140void
141Log::Printf(const char *format, ...)
142{
143    va_list args;
144    va_start (args, format);
145    PrintfWithFlagsVarArg (0, format, args);
146    va_end (args);
147}
148
149void
150Log::VAPrintf (const char *format, va_list args)
151{
152    PrintfWithFlagsVarArg (0, format, args);
153}
154
155
156//----------------------------------------------------------------------
157// Simple variable argument logging with flags.
158//----------------------------------------------------------------------
159void
160Log::PrintfWithFlags (uint32_t flags, const char *format, ...)
161{
162    va_list args;
163    va_start (args, format);
164    PrintfWithFlagsVarArg (flags, format, args);
165    va_end (args);
166}
167
168//----------------------------------------------------------------------
169// Print debug strings if and only if the global debug option is set to
170// a non-zero value.
171//----------------------------------------------------------------------
172void
173Log::Debug (const char *format, ...)
174{
175    if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
176    {
177        va_list args;
178        va_start (args, format);
179        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args);
180        va_end (args);
181    }
182}
183
184
185//----------------------------------------------------------------------
186// Print debug strings if and only if the global debug option is set to
187// a non-zero value.
188//----------------------------------------------------------------------
189void
190Log::DebugVerbose (const char *format, ...)
191{
192    if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
193    {
194        va_list args;
195        va_start (args, format);
196        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args);
197        va_end (args);
198    }
199}
200
201
202//----------------------------------------------------------------------
203// Log only if all of the bits are set
204//----------------------------------------------------------------------
205void
206Log::LogIf (uint32_t bits, const char *format, ...)
207{
208    if (m_options.AllSet (bits))
209    {
210        va_list args;
211        va_start (args, format);
212        PrintfWithFlagsVarArg (0, format, args);
213        va_end (args);
214    }
215}
216
217
218//----------------------------------------------------------------------
219// Printing of errors that are not fatal.
220//----------------------------------------------------------------------
221void
222Log::Error (const char *format, ...)
223{
224    char *arg_msg = NULL;
225    va_list args;
226    va_start (args, format);
227    ::vasprintf (&arg_msg, format, args);
228    va_end (args);
229
230    if (arg_msg != NULL)
231    {
232        PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg);
233        free (arg_msg);
234    }
235}
236
237//----------------------------------------------------------------------
238// Printing of errors that ARE fatal. Exit with ERR exit code
239// immediately.
240//----------------------------------------------------------------------
241void
242Log::FatalError (int err, const char *format, ...)
243{
244    char *arg_msg = NULL;
245    va_list args;
246    va_start (args, format);
247    ::vasprintf (&arg_msg, format, args);
248    va_end (args);
249
250    if (arg_msg != NULL)
251    {
252        PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg);
253        ::free (arg_msg);
254    }
255    ::exit (err);
256}
257
258
259//----------------------------------------------------------------------
260// Printing of warnings that are not fatal only if verbose mode is
261// enabled.
262//----------------------------------------------------------------------
263void
264Log::Verbose (const char *format, ...)
265{
266    if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
267    {
268        va_list args;
269        va_start (args, format);
270        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args);
271        va_end (args);
272    }
273}
274
275//----------------------------------------------------------------------
276// Printing of warnings that are not fatal only if verbose mode is
277// enabled.
278//----------------------------------------------------------------------
279void
280Log::WarningVerbose (const char *format, ...)
281{
282    if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
283    {
284        char *arg_msg = NULL;
285        va_list args;
286        va_start (args, format);
287        ::vasprintf (&arg_msg, format, args);
288        va_end (args);
289
290        if (arg_msg != NULL)
291        {
292            PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg);
293            free (arg_msg);
294        }
295    }
296}
297//----------------------------------------------------------------------
298// Printing of warnings that are not fatal.
299//----------------------------------------------------------------------
300void
301Log::Warning (const char *format, ...)
302{
303    char *arg_msg = NULL;
304    va_list args;
305    va_start (args, format);
306    ::vasprintf (&arg_msg, format, args);
307    va_end (args);
308
309    if (arg_msg != NULL)
310    {
311        PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg);
312        free (arg_msg);
313    }
314}
315
316typedef std::map <ConstString, Log::Callbacks> CallbackMap;
317typedef CallbackMap::iterator CallbackMapIter;
318
319typedef std::map <ConstString, LogChannelSP> LogChannelMap;
320typedef LogChannelMap::iterator LogChannelMapIter;
321
322
323// Surround our callback map with a singleton function so we don't have any
324// global initializers.
325static CallbackMap &
326GetCallbackMap ()
327{
328    static CallbackMap g_callback_map;
329    return g_callback_map;
330}
331
332static LogChannelMap &
333GetChannelMap ()
334{
335    static LogChannelMap g_channel_map;
336    return g_channel_map;
337}
338
339void
340Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
341{
342    GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
343}
344
345bool
346Log::UnregisterLogChannel (const ConstString &channel)
347{
348    return GetCallbackMap().erase(channel) != 0;
349}
350
351bool
352Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
353{
354    CallbackMap &callback_map = GetCallbackMap ();
355    CallbackMapIter pos = callback_map.find(channel);
356    if (pos != callback_map.end())
357    {
358        log_callbacks = pos->second;
359        return true;
360    }
361    ::memset (&log_callbacks, 0, sizeof(log_callbacks));
362    return false;
363}
364
365void
366Log::EnableAllLogChannels
367(
368    StreamSP &log_stream_sp,
369    uint32_t log_options,
370    const char **categories,
371    Stream *feedback_strm
372)
373{
374    CallbackMap &callback_map = GetCallbackMap ();
375    CallbackMapIter pos, end = callback_map.end();
376
377    for (pos = callback_map.begin(); pos != end; ++pos)
378        pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
379
380    LogChannelMap &channel_map = GetChannelMap ();
381    LogChannelMapIter channel_pos, channel_end = channel_map.end();
382    for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
383    {
384        channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
385    }
386
387}
388
389void
390Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
391{
392    LogChannelMap &map = GetChannelMap ();
393    LogChannelMapIter pos, end = map.end();
394    for (pos = map.begin(); pos != end; ++pos)
395    {
396        const char *pos_channel_name = pos->first.GetCString();
397        if (channel_name && channel_name[0])
398        {
399            if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
400            {
401                matches.AppendString(pos_channel_name);
402            }
403        }
404        else
405            matches.AppendString(pos_channel_name);
406
407    }
408}
409
410void
411Log::DisableAllLogChannels (Stream *feedback_strm)
412{
413    CallbackMap &callback_map = GetCallbackMap ();
414    CallbackMapIter pos, end = callback_map.end();
415    const char *categories[1] = {NULL};
416
417    for (pos = callback_map.begin(); pos != end; ++pos)
418        pos->second.disable (categories, feedback_strm);
419
420    LogChannelMap &channel_map = GetChannelMap ();
421    LogChannelMapIter channel_pos, channel_end = channel_map.end();
422    for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
423        channel_pos->second->Disable (categories, feedback_strm);
424}
425
426void
427Log::Initialize()
428{
429    Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
430    Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
431}
432
433void
434Log::Terminate ()
435{
436    DisableAllLogChannels (NULL);
437}
438
439void
440Log::ListAllLogChannels (Stream *strm)
441{
442    CallbackMap &callback_map = GetCallbackMap ();
443    LogChannelMap &channel_map = GetChannelMap ();
444
445    if (callback_map.empty() && channel_map.empty())
446    {
447        strm->PutCString ("No logging channels are currently registered.\n");
448        return;
449    }
450
451    CallbackMapIter pos, end = callback_map.end();
452    for (pos = callback_map.begin(); pos != end; ++pos)
453        pos->second.list_categories (strm);
454
455    uint32_t idx = 0;
456    const char *name;
457    for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
458    {
459        LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
460        if (log_channel_sp)
461            log_channel_sp->ListCategories (strm);
462    }
463}
464
465bool
466Log::GetVerbose() const
467{
468    // FIXME: This has to be centralized between the stream and the log...
469    if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
470        return true;
471
472    if (m_stream_sp)
473        return m_stream_sp->GetVerbose();
474    return false;
475}
476
477//------------------------------------------------------------------
478// Returns true if the debug flag bit is set in this stream.
479//------------------------------------------------------------------
480bool
481Log::GetDebug() const
482{
483    if (m_stream_sp)
484        return m_stream_sp->GetDebug();
485    return false;
486}
487
488
489LogChannelSP
490LogChannel::FindPlugin (const char *plugin_name)
491{
492    LogChannelSP log_channel_sp;
493    LogChannelMap &channel_map = GetChannelMap ();
494    ConstString log_channel_name (plugin_name);
495    LogChannelMapIter pos = channel_map.find (log_channel_name);
496    if (pos == channel_map.end())
497    {
498        ConstString const_plugin_name (plugin_name);
499        LogChannelCreateInstance create_callback  = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
500        if (create_callback)
501        {
502            log_channel_sp.reset(create_callback());
503            if (log_channel_sp)
504            {
505                // Cache the one and only loaded instance of each log channel
506                // plug-in after it has been loaded once.
507                channel_map[log_channel_name] = log_channel_sp;
508            }
509        }
510    }
511    else
512    {
513        // We have already loaded an instance of this log channel class,
514        // so just return the cached instance.
515        log_channel_sp = pos->second;
516    }
517    return log_channel_sp;
518}
519
520LogChannel::LogChannel () :
521    m_log_ap ()
522{
523}
524
525LogChannel::~LogChannel ()
526{
527}
528
529
530