1254721Semaste//===-- Log.cpp -------------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste// C Includes
13254721Semaste#include <stdio.h>
14254721Semaste#include <stdarg.h>
15254721Semaste#include <stdlib.h>
16254721Semaste
17254721Semaste// C++ Includes
18254721Semaste#include <map>
19254721Semaste#include <string>
20254721Semaste
21254721Semaste// Other libraries and framework includes
22254721Semaste// Project includes
23254721Semaste#include "lldb/Core/Debugger.h"
24254721Semaste#include "lldb/Core/Log.h"
25254721Semaste#include "lldb/Core/PluginManager.h"
26254721Semaste#include "lldb/Core/StreamFile.h"
27254721Semaste#include "lldb/Core/StreamString.h"
28254721Semaste#include "lldb/Host/Host.h"
29254721Semaste#include "lldb/Host/TimeValue.h"
30254721Semaste#include "lldb/Host/Mutex.h"
31254721Semaste#include "lldb/Interpreter/Args.h"
32254721Semasteusing namespace lldb;
33254721Semasteusing namespace lldb_private;
34254721Semaste
35254721SemasteLog::Log () :
36254721Semaste    m_stream_sp(),
37254721Semaste    m_options(0),
38254721Semaste    m_mask_bits(0)
39254721Semaste{
40254721Semaste}
41254721Semaste
42254721SemasteLog::Log (const StreamSP &stream_sp) :
43254721Semaste    m_stream_sp(stream_sp),
44254721Semaste    m_options(0),
45254721Semaste    m_mask_bits(0)
46254721Semaste{
47254721Semaste}
48254721Semaste
49254721SemasteLog::~Log ()
50254721Semaste{
51254721Semaste}
52254721Semaste
53254721SemasteFlags &
54254721SemasteLog::GetOptions()
55254721Semaste{
56254721Semaste    return m_options;
57254721Semaste}
58254721Semaste
59254721Semasteconst Flags &
60254721SemasteLog::GetOptions() const
61254721Semaste{
62254721Semaste    return m_options;
63254721Semaste}
64254721Semaste
65254721SemasteFlags &
66254721SemasteLog::GetMask()
67254721Semaste{
68254721Semaste    return m_mask_bits;
69254721Semaste}
70254721Semaste
71254721Semasteconst Flags &
72254721SemasteLog::GetMask() const
73254721Semaste{
74254721Semaste    return m_mask_bits;
75254721Semaste}
76254721Semaste
77254721Semaste
78254721Semaste//----------------------------------------------------------------------
79254721Semaste// All logging eventually boils down to this function call. If we have
80254721Semaste// a callback registered, then we call the logging callback. If we have
81254721Semaste// a valid file handle, we also log to the file.
82254721Semaste//----------------------------------------------------------------------
83254721Semastevoid
84254721SemasteLog::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args)
85254721Semaste{
86269024Semaste    // Make a copy of our stream shared pointer in case someone disables our
87269024Semaste    // log while we are logging and releases the stream
88269024Semaste    StreamSP stream_sp(m_stream_sp);
89269024Semaste    if (stream_sp)
90254721Semaste    {
91254721Semaste        static uint32_t g_sequence_id = 0;
92254721Semaste        StreamString header;
93254721Semaste		// Enabling the thread safe logging actually deadlocks right now.
94254721Semaste		// Need to fix this at some point.
95254721Semaste//        static Mutex g_LogThreadedMutex(Mutex::eMutexTypeRecursive);
96254721Semaste//        Mutex::Locker locker (g_LogThreadedMutex);
97254721Semaste
98254721Semaste        // Add a sequence ID if requested
99254721Semaste        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
100254721Semaste            header.Printf ("%u ", ++g_sequence_id);
101254721Semaste
102254721Semaste        // Timestamp if requested
103254721Semaste        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
104254721Semaste        {
105263363Semaste            TimeValue now = TimeValue::Now();
106263363Semaste            header.Printf ("%9d.%6.6d ", now.seconds(), now.nanoseconds());
107254721Semaste        }
108254721Semaste
109254721Semaste        // Add the process and thread if requested
110254721Semaste        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
111254721Semaste            header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
112254721Semaste
113254721Semaste        // Add the process and thread if requested
114254721Semaste        if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
115254721Semaste        {
116254721Semaste            std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID()));
117254721Semaste            if (!thread_name.empty())
118254721Semaste                header.Printf ("%s ", thread_name.c_str());
119254721Semaste        }
120254721Semaste
121254721Semaste        header.PrintfVarArg (format, args);
122269024Semaste        stream_sp->Printf("%s\n", header.GetData());
123254721Semaste
124254721Semaste        if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE))
125269024Semaste            Host::Backtrace (*stream_sp, 1024);
126269024Semaste        stream_sp->Flush();
127254721Semaste    }
128254721Semaste}
129254721Semaste
130254721Semaste
131254721Semastevoid
132254721SemasteLog::PutCString (const char *cstr)
133254721Semaste{
134254721Semaste    Printf ("%s", cstr);
135254721Semaste}
136254721Semaste
137254721Semaste
138254721Semaste//----------------------------------------------------------------------
139254721Semaste// Simple variable argument logging with flags.
140254721Semaste//----------------------------------------------------------------------
141254721Semastevoid
142254721SemasteLog::Printf(const char *format, ...)
143254721Semaste{
144254721Semaste    va_list args;
145254721Semaste    va_start (args, format);
146254721Semaste    PrintfWithFlagsVarArg (0, format, args);
147254721Semaste    va_end (args);
148254721Semaste}
149254721Semaste
150254721Semastevoid
151254721SemasteLog::VAPrintf (const char *format, va_list args)
152254721Semaste{
153254721Semaste    PrintfWithFlagsVarArg (0, format, args);
154254721Semaste}
155254721Semaste
156254721Semaste
157254721Semaste//----------------------------------------------------------------------
158254721Semaste// Simple variable argument logging with flags.
159254721Semaste//----------------------------------------------------------------------
160254721Semastevoid
161254721SemasteLog::PrintfWithFlags (uint32_t flags, const char *format, ...)
162254721Semaste{
163254721Semaste    va_list args;
164254721Semaste    va_start (args, format);
165254721Semaste    PrintfWithFlagsVarArg (flags, format, args);
166254721Semaste    va_end (args);
167254721Semaste}
168254721Semaste
169254721Semaste//----------------------------------------------------------------------
170254721Semaste// Print debug strings if and only if the global debug option is set to
171254721Semaste// a non-zero value.
172254721Semaste//----------------------------------------------------------------------
173254721Semastevoid
174254721SemasteLog::Debug (const char *format, ...)
175254721Semaste{
176254721Semaste    if (GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
177254721Semaste    {
178254721Semaste        va_list args;
179254721Semaste        va_start (args, format);
180254721Semaste        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG, format, args);
181254721Semaste        va_end (args);
182254721Semaste    }
183254721Semaste}
184254721Semaste
185254721Semaste
186254721Semaste//----------------------------------------------------------------------
187254721Semaste// Print debug strings if and only if the global debug option is set to
188254721Semaste// a non-zero value.
189254721Semaste//----------------------------------------------------------------------
190254721Semastevoid
191254721SemasteLog::DebugVerbose (const char *format, ...)
192254721Semaste{
193254721Semaste    if (GetOptions().AllSet (LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
194254721Semaste    {
195254721Semaste        va_list args;
196254721Semaste        va_start (args, format);
197254721Semaste        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_DEBUG | LLDB_LOG_FLAG_VERBOSE, format, args);
198254721Semaste        va_end (args);
199254721Semaste    }
200254721Semaste}
201254721Semaste
202254721Semaste
203254721Semaste//----------------------------------------------------------------------
204254721Semaste// Log only if all of the bits are set
205254721Semaste//----------------------------------------------------------------------
206254721Semastevoid
207254721SemasteLog::LogIf (uint32_t bits, const char *format, ...)
208254721Semaste{
209254721Semaste    if (m_options.AllSet (bits))
210254721Semaste    {
211254721Semaste        va_list args;
212254721Semaste        va_start (args, format);
213254721Semaste        PrintfWithFlagsVarArg (0, format, args);
214254721Semaste        va_end (args);
215254721Semaste    }
216254721Semaste}
217254721Semaste
218254721Semaste
219254721Semaste//----------------------------------------------------------------------
220254721Semaste// Printing of errors that are not fatal.
221254721Semaste//----------------------------------------------------------------------
222254721Semastevoid
223254721SemasteLog::Error (const char *format, ...)
224254721Semaste{
225254721Semaste    char *arg_msg = NULL;
226254721Semaste    va_list args;
227254721Semaste    va_start (args, format);
228254721Semaste    ::vasprintf (&arg_msg, format, args);
229254721Semaste    va_end (args);
230254721Semaste
231254721Semaste    if (arg_msg != NULL)
232254721Semaste    {
233254721Semaste        PrintfWithFlags (LLDB_LOG_FLAG_ERROR, "error: %s", arg_msg);
234254721Semaste        free (arg_msg);
235254721Semaste    }
236254721Semaste}
237254721Semaste
238254721Semaste//----------------------------------------------------------------------
239254721Semaste// Printing of errors that ARE fatal. Exit with ERR exit code
240254721Semaste// immediately.
241254721Semaste//----------------------------------------------------------------------
242254721Semastevoid
243254721SemasteLog::FatalError (int err, const char *format, ...)
244254721Semaste{
245254721Semaste    char *arg_msg = NULL;
246254721Semaste    va_list args;
247254721Semaste    va_start (args, format);
248254721Semaste    ::vasprintf (&arg_msg, format, args);
249254721Semaste    va_end (args);
250254721Semaste
251254721Semaste    if (arg_msg != NULL)
252254721Semaste    {
253254721Semaste        PrintfWithFlags (LLDB_LOG_FLAG_ERROR | LLDB_LOG_FLAG_FATAL, "error: %s", arg_msg);
254254721Semaste        ::free (arg_msg);
255254721Semaste    }
256254721Semaste    ::exit (err);
257254721Semaste}
258254721Semaste
259254721Semaste
260254721Semaste//----------------------------------------------------------------------
261254721Semaste// Printing of warnings that are not fatal only if verbose mode is
262254721Semaste// enabled.
263254721Semaste//----------------------------------------------------------------------
264254721Semastevoid
265254721SemasteLog::Verbose (const char *format, ...)
266254721Semaste{
267254721Semaste    if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
268254721Semaste    {
269254721Semaste        va_list args;
270254721Semaste        va_start (args, format);
271254721Semaste        PrintfWithFlagsVarArg (LLDB_LOG_FLAG_VERBOSE, format, args);
272254721Semaste        va_end (args);
273254721Semaste    }
274254721Semaste}
275254721Semaste
276254721Semaste//----------------------------------------------------------------------
277254721Semaste// Printing of warnings that are not fatal only if verbose mode is
278254721Semaste// enabled.
279254721Semaste//----------------------------------------------------------------------
280254721Semastevoid
281254721SemasteLog::WarningVerbose (const char *format, ...)
282254721Semaste{
283254721Semaste    if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
284254721Semaste    {
285254721Semaste        char *arg_msg = NULL;
286254721Semaste        va_list args;
287254721Semaste        va_start (args, format);
288254721Semaste        ::vasprintf (&arg_msg, format, args);
289254721Semaste        va_end (args);
290254721Semaste
291254721Semaste        if (arg_msg != NULL)
292254721Semaste        {
293254721Semaste            PrintfWithFlags (LLDB_LOG_FLAG_WARNING | LLDB_LOG_FLAG_VERBOSE, "warning: %s", arg_msg);
294254721Semaste            free (arg_msg);
295254721Semaste        }
296254721Semaste    }
297254721Semaste}
298254721Semaste//----------------------------------------------------------------------
299254721Semaste// Printing of warnings that are not fatal.
300254721Semaste//----------------------------------------------------------------------
301254721Semastevoid
302254721SemasteLog::Warning (const char *format, ...)
303254721Semaste{
304254721Semaste    char *arg_msg = NULL;
305254721Semaste    va_list args;
306254721Semaste    va_start (args, format);
307254721Semaste    ::vasprintf (&arg_msg, format, args);
308254721Semaste    va_end (args);
309254721Semaste
310254721Semaste    if (arg_msg != NULL)
311254721Semaste    {
312254721Semaste        PrintfWithFlags (LLDB_LOG_FLAG_WARNING, "warning: %s", arg_msg);
313254721Semaste        free (arg_msg);
314254721Semaste    }
315254721Semaste}
316254721Semaste
317254721Semastetypedef std::map <ConstString, Log::Callbacks> CallbackMap;
318254721Semastetypedef CallbackMap::iterator CallbackMapIter;
319254721Semaste
320254721Semastetypedef std::map <ConstString, LogChannelSP> LogChannelMap;
321254721Semastetypedef LogChannelMap::iterator LogChannelMapIter;
322254721Semaste
323254721Semaste
324254721Semaste// Surround our callback map with a singleton function so we don't have any
325254721Semaste// global initializers.
326254721Semastestatic CallbackMap &
327254721SemasteGetCallbackMap ()
328254721Semaste{
329254721Semaste    static CallbackMap g_callback_map;
330254721Semaste    return g_callback_map;
331254721Semaste}
332254721Semaste
333254721Semastestatic LogChannelMap &
334254721SemasteGetChannelMap ()
335254721Semaste{
336254721Semaste    static LogChannelMap g_channel_map;
337254721Semaste    return g_channel_map;
338254721Semaste}
339254721Semaste
340254721Semastevoid
341254721SemasteLog::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
342254721Semaste{
343254721Semaste    GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
344254721Semaste}
345254721Semaste
346254721Semastebool
347254721SemasteLog::UnregisterLogChannel (const ConstString &channel)
348254721Semaste{
349254721Semaste    return GetCallbackMap().erase(channel) != 0;
350254721Semaste}
351254721Semaste
352254721Semastebool
353254721SemasteLog::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
354254721Semaste{
355254721Semaste    CallbackMap &callback_map = GetCallbackMap ();
356254721Semaste    CallbackMapIter pos = callback_map.find(channel);
357254721Semaste    if (pos != callback_map.end())
358254721Semaste    {
359254721Semaste        log_callbacks = pos->second;
360254721Semaste        return true;
361254721Semaste    }
362254721Semaste    ::memset (&log_callbacks, 0, sizeof(log_callbacks));
363254721Semaste    return false;
364254721Semaste}
365254721Semaste
366254721Semastevoid
367254721SemasteLog::EnableAllLogChannels
368254721Semaste(
369254721Semaste    StreamSP &log_stream_sp,
370254721Semaste    uint32_t log_options,
371254721Semaste    const char **categories,
372254721Semaste    Stream *feedback_strm
373254721Semaste)
374254721Semaste{
375254721Semaste    CallbackMap &callback_map = GetCallbackMap ();
376254721Semaste    CallbackMapIter pos, end = callback_map.end();
377254721Semaste
378254721Semaste    for (pos = callback_map.begin(); pos != end; ++pos)
379254721Semaste        pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
380254721Semaste
381254721Semaste    LogChannelMap &channel_map = GetChannelMap ();
382254721Semaste    LogChannelMapIter channel_pos, channel_end = channel_map.end();
383254721Semaste    for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
384254721Semaste    {
385254721Semaste        channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
386254721Semaste    }
387254721Semaste
388254721Semaste}
389254721Semaste
390254721Semastevoid
391254721SemasteLog::AutoCompleteChannelName (const char *channel_name, StringList &matches)
392254721Semaste{
393254721Semaste    LogChannelMap &map = GetChannelMap ();
394254721Semaste    LogChannelMapIter pos, end = map.end();
395254721Semaste    for (pos = map.begin(); pos != end; ++pos)
396254721Semaste    {
397254721Semaste        const char *pos_channel_name = pos->first.GetCString();
398254721Semaste        if (channel_name && channel_name[0])
399254721Semaste        {
400254721Semaste            if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
401254721Semaste            {
402254721Semaste                matches.AppendString(pos_channel_name);
403254721Semaste            }
404254721Semaste        }
405254721Semaste        else
406254721Semaste            matches.AppendString(pos_channel_name);
407254721Semaste
408254721Semaste    }
409254721Semaste}
410254721Semaste
411254721Semastevoid
412254721SemasteLog::DisableAllLogChannels (Stream *feedback_strm)
413254721Semaste{
414254721Semaste    CallbackMap &callback_map = GetCallbackMap ();
415254721Semaste    CallbackMapIter pos, end = callback_map.end();
416254721Semaste    const char *categories[1] = {NULL};
417254721Semaste
418254721Semaste    for (pos = callback_map.begin(); pos != end; ++pos)
419254721Semaste        pos->second.disable (categories, feedback_strm);
420254721Semaste
421254721Semaste    LogChannelMap &channel_map = GetChannelMap ();
422254721Semaste    LogChannelMapIter channel_pos, channel_end = channel_map.end();
423254721Semaste    for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
424254721Semaste        channel_pos->second->Disable (categories, feedback_strm);
425254721Semaste}
426254721Semaste
427254721Semastevoid
428254721SemasteLog::Initialize()
429254721Semaste{
430254721Semaste    Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
431254721Semaste    Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
432254721Semaste}
433254721Semaste
434254721Semastevoid
435254721SemasteLog::Terminate ()
436254721Semaste{
437254721Semaste    DisableAllLogChannels (NULL);
438254721Semaste}
439254721Semaste
440254721Semastevoid
441254721SemasteLog::ListAllLogChannels (Stream *strm)
442254721Semaste{
443254721Semaste    CallbackMap &callback_map = GetCallbackMap ();
444254721Semaste    LogChannelMap &channel_map = GetChannelMap ();
445254721Semaste
446254721Semaste    if (callback_map.empty() && channel_map.empty())
447254721Semaste    {
448254721Semaste        strm->PutCString ("No logging channels are currently registered.\n");
449254721Semaste        return;
450254721Semaste    }
451254721Semaste
452254721Semaste    CallbackMapIter pos, end = callback_map.end();
453254721Semaste    for (pos = callback_map.begin(); pos != end; ++pos)
454254721Semaste        pos->second.list_categories (strm);
455254721Semaste
456254721Semaste    uint32_t idx = 0;
457254721Semaste    const char *name;
458254721Semaste    for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != NULL; ++idx)
459254721Semaste    {
460254721Semaste        LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
461254721Semaste        if (log_channel_sp)
462254721Semaste            log_channel_sp->ListCategories (strm);
463254721Semaste    }
464254721Semaste}
465254721Semaste
466254721Semastebool
467254721SemasteLog::GetVerbose() const
468254721Semaste{
469254721Semaste    // FIXME: This has to be centralized between the stream and the log...
470254721Semaste    if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
471254721Semaste        return true;
472254721Semaste
473269024Semaste    // Make a copy of our stream shared pointer in case someone disables our
474269024Semaste    // log while we are logging and releases the stream
475269024Semaste    StreamSP stream_sp(m_stream_sp);
476269024Semaste    if (stream_sp)
477269024Semaste        return stream_sp->GetVerbose();
478254721Semaste    return false;
479254721Semaste}
480254721Semaste
481254721Semaste//------------------------------------------------------------------
482254721Semaste// Returns true if the debug flag bit is set in this stream.
483254721Semaste//------------------------------------------------------------------
484254721Semastebool
485254721SemasteLog::GetDebug() const
486254721Semaste{
487269024Semaste    // Make a copy of our stream shared pointer in case someone disables our
488269024Semaste    // log while we are logging and releases the stream
489269024Semaste    StreamSP stream_sp(m_stream_sp);
490269024Semaste    if (stream_sp)
491269024Semaste        return stream_sp->GetDebug();
492254721Semaste    return false;
493254721Semaste}
494254721Semaste
495254721Semaste
496254721SemasteLogChannelSP
497254721SemasteLogChannel::FindPlugin (const char *plugin_name)
498254721Semaste{
499254721Semaste    LogChannelSP log_channel_sp;
500254721Semaste    LogChannelMap &channel_map = GetChannelMap ();
501254721Semaste    ConstString log_channel_name (plugin_name);
502254721Semaste    LogChannelMapIter pos = channel_map.find (log_channel_name);
503254721Semaste    if (pos == channel_map.end())
504254721Semaste    {
505254721Semaste        ConstString const_plugin_name (plugin_name);
506254721Semaste        LogChannelCreateInstance create_callback  = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
507254721Semaste        if (create_callback)
508254721Semaste        {
509254721Semaste            log_channel_sp.reset(create_callback());
510254721Semaste            if (log_channel_sp)
511254721Semaste            {
512254721Semaste                // Cache the one and only loaded instance of each log channel
513254721Semaste                // plug-in after it has been loaded once.
514254721Semaste                channel_map[log_channel_name] = log_channel_sp;
515254721Semaste            }
516254721Semaste        }
517254721Semaste    }
518254721Semaste    else
519254721Semaste    {
520254721Semaste        // We have already loaded an instance of this log channel class,
521254721Semaste        // so just return the cached instance.
522254721Semaste        log_channel_sp = pos->second;
523254721Semaste    }
524254721Semaste    return log_channel_sp;
525254721Semaste}
526254721Semaste
527254721SemasteLogChannel::LogChannel () :
528254721Semaste    m_log_ap ()
529254721Semaste{
530254721Semaste}
531254721Semaste
532254721SemasteLogChannel::~LogChannel ()
533254721Semaste{
534254721Semaste}
535254721Semaste
536254721Semaste
537