130fdc8d8SChris Lattner //===-- CommandObjectLog.cpp ------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectLog.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/lldb-private-log.h"
1730fdc8d8SChris Lattner 
1840af72e1SJim Ingham #include "lldb/Interpreter/Args.h"
1930fdc8d8SChris Lattner #include "lldb/Core/Debugger.h"
2030fdc8d8SChris Lattner #include "lldb/Core/FileSpec.h"
2130fdc8d8SChris Lattner #include "lldb/Core/Log.h"
2230fdc8d8SChris Lattner #include "lldb/Core/Module.h"
2340af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2430fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2530fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2630fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
2730fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
2830fdc8d8SChris Lattner 
296611103cSGreg Clayton #include "lldb/Core/Debugger.h"
304be3990fSSean Callanan #include "lldb/Interpreter/CommandInterpreter.h"
3130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
3230fdc8d8SChris Lattner 
3330fdc8d8SChris Lattner #include "lldb/Symbol/LineTable.h"
3430fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
3530fdc8d8SChris Lattner #include "lldb/Symbol/SymbolFile.h"
3630fdc8d8SChris Lattner #include "lldb/Symbol/SymbolVendor.h"
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
3930fdc8d8SChris Lattner #include "lldb/Target/Target.h"
4030fdc8d8SChris Lattner 
4130fdc8d8SChris Lattner using namespace lldb;
4230fdc8d8SChris Lattner using namespace lldb_private;
4330fdc8d8SChris Lattner 
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner static LogChannelSP
4630fdc8d8SChris Lattner GetLogChannelPluginForChannel (const char *channel)
4730fdc8d8SChris Lattner {
4830fdc8d8SChris Lattner     std::string log_channel_plugin_name(channel);
4930fdc8d8SChris Lattner     log_channel_plugin_name += LogChannel::GetPluginSuffix();
5030fdc8d8SChris Lattner     LogChannelSP log_channel_sp (LogChannel::FindPlugin (log_channel_plugin_name.c_str()));
5130fdc8d8SChris Lattner     return log_channel_sp;
5230fdc8d8SChris Lattner }
5330fdc8d8SChris Lattner 
5430fdc8d8SChris Lattner 
5530fdc8d8SChris Lattner class CommandObjectLogEnable : public CommandObject
5630fdc8d8SChris Lattner {
5730fdc8d8SChris Lattner public:
5830fdc8d8SChris Lattner     //------------------------------------------------------------------
5930fdc8d8SChris Lattner     // Constructors and Destructors
6030fdc8d8SChris Lattner     //------------------------------------------------------------------
61a7015092SGreg Clayton     CommandObjectLogEnable(CommandInterpreter &interpreter) :
62a7015092SGreg Clayton         CommandObject (interpreter,
63a7015092SGreg Clayton                        "log enable",
6430fdc8d8SChris Lattner                        "Enable logging for a single log channel.",
65*405fe67fSCaroline Tice                         NULL)
6630fdc8d8SChris Lattner     {
67*405fe67fSCaroline Tice         CommandArgumentEntry arg;
68*405fe67fSCaroline Tice         CommandArgumentData channel_arg;
69*405fe67fSCaroline Tice 
70*405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
71*405fe67fSCaroline Tice         channel_arg.arg_type = eArgTypeLogChannel;
72*405fe67fSCaroline Tice         channel_arg.arg_repetition = eArgRepeatPlain;
73*405fe67fSCaroline Tice 
74*405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
75*405fe67fSCaroline Tice         arg.push_back (channel_arg);
76*405fe67fSCaroline Tice 
77*405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
78*405fe67fSCaroline Tice         m_arguments.push_back (arg);
7930fdc8d8SChris Lattner     }
8030fdc8d8SChris Lattner 
8130fdc8d8SChris Lattner     virtual
8230fdc8d8SChris Lattner     ~CommandObjectLogEnable()
8330fdc8d8SChris Lattner     {
8430fdc8d8SChris Lattner     }
8530fdc8d8SChris Lattner 
8630fdc8d8SChris Lattner     Options *
8730fdc8d8SChris Lattner     GetOptions ()
8830fdc8d8SChris Lattner     {
8930fdc8d8SChris Lattner         return &m_options;
9030fdc8d8SChris Lattner     }
9130fdc8d8SChris Lattner 
9230fdc8d8SChris Lattner     virtual bool
93a7015092SGreg Clayton     Execute (Args& args,
9430fdc8d8SChris Lattner              CommandReturnObject &result)
9530fdc8d8SChris Lattner     {
9630fdc8d8SChris Lattner         if (args.GetArgumentCount() < 1)
9730fdc8d8SChris Lattner         {
98e3d26315SCaroline Tice             result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
9930fdc8d8SChris Lattner         }
10030fdc8d8SChris Lattner         else
10130fdc8d8SChris Lattner         {
10230fdc8d8SChris Lattner             Log::Callbacks log_callbacks;
10330fdc8d8SChris Lattner 
10430fdc8d8SChris Lattner             std::string channel(args.GetArgumentAtIndex(0));
10530fdc8d8SChris Lattner             args.Shift ();  // Shift off the channel
10630fdc8d8SChris Lattner             StreamSP log_stream_sp;
10730fdc8d8SChris Lattner 
10830fdc8d8SChris Lattner             if (m_options.log_file.empty())
10930fdc8d8SChris Lattner             {
110a7015092SGreg Clayton                 log_stream_sp.reset(new StreamFile(m_interpreter.GetDebugger().GetOutputFileHandle()));
11130fdc8d8SChris Lattner             }
11230fdc8d8SChris Lattner             else
11330fdc8d8SChris Lattner             {
11430fdc8d8SChris Lattner                 LogStreamMap::iterator pos = m_log_streams.find(m_options.log_file);
11530fdc8d8SChris Lattner                 if (pos == m_log_streams.end())
11630fdc8d8SChris Lattner                 {
11730fdc8d8SChris Lattner                     log_stream_sp.reset (new StreamFile (m_options.log_file.c_str(), "w"));
11830fdc8d8SChris Lattner                     m_log_streams[m_options.log_file] = log_stream_sp;
11930fdc8d8SChris Lattner                 }
12030fdc8d8SChris Lattner                 else
12130fdc8d8SChris Lattner                     log_stream_sp = pos->second;
12230fdc8d8SChris Lattner             }
12330fdc8d8SChris Lattner             assert (log_stream_sp.get());
12430fdc8d8SChris Lattner             uint32_t log_options = m_options.log_options;
12530fdc8d8SChris Lattner             if (log_options == 0)
12630fdc8d8SChris Lattner                 log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
12730fdc8d8SChris Lattner             if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
12830fdc8d8SChris Lattner             {
12930fdc8d8SChris Lattner                 log_callbacks.enable (log_stream_sp, log_options, args, &result.GetErrorStream());
13030fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishNoResult);
13130fdc8d8SChris Lattner             }
13230fdc8d8SChris Lattner             else
13330fdc8d8SChris Lattner             {
13430fdc8d8SChris Lattner                 LogChannelSP log_channel_sp (GetLogChannelPluginForChannel(channel.c_str()));
13530fdc8d8SChris Lattner                 if (log_channel_sp)
13630fdc8d8SChris Lattner                 {
13730fdc8d8SChris Lattner                     if (log_channel_sp->Enable (log_stream_sp, log_options, &result.GetErrorStream(), args))
13830fdc8d8SChris Lattner                     {
13930fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
14030fdc8d8SChris Lattner                     }
14130fdc8d8SChris Lattner                     else
14230fdc8d8SChris Lattner                     {
14330fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
14430fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
14530fdc8d8SChris Lattner                     }
14630fdc8d8SChris Lattner                 }
14730fdc8d8SChris Lattner                 else
14830fdc8d8SChris Lattner                 {
14930fdc8d8SChris Lattner                     result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str());
15030fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
15130fdc8d8SChris Lattner                 }
15230fdc8d8SChris Lattner             }
15330fdc8d8SChris Lattner         }
15430fdc8d8SChris Lattner         return result.Succeeded();
15530fdc8d8SChris Lattner     }
15630fdc8d8SChris Lattner 
15730fdc8d8SChris Lattner 
15830fdc8d8SChris Lattner     class CommandOptions : public Options
15930fdc8d8SChris Lattner     {
16030fdc8d8SChris Lattner     public:
16130fdc8d8SChris Lattner 
16230fdc8d8SChris Lattner         CommandOptions () :
16330fdc8d8SChris Lattner             Options (),
16430fdc8d8SChris Lattner             log_file (),
16530fdc8d8SChris Lattner             log_options (0)
16630fdc8d8SChris Lattner         {
16730fdc8d8SChris Lattner         }
16830fdc8d8SChris Lattner 
16930fdc8d8SChris Lattner 
17030fdc8d8SChris Lattner         virtual
17130fdc8d8SChris Lattner         ~CommandOptions ()
17230fdc8d8SChris Lattner         {
17330fdc8d8SChris Lattner         }
17430fdc8d8SChris Lattner 
17530fdc8d8SChris Lattner         virtual Error
17630fdc8d8SChris Lattner         SetOptionValue (int option_idx, const char *option_arg)
17730fdc8d8SChris Lattner         {
17830fdc8d8SChris Lattner             Error error;
17930fdc8d8SChris Lattner             char short_option = (char) m_getopt_table[option_idx].val;
18030fdc8d8SChris Lattner 
18130fdc8d8SChris Lattner             switch (short_option)
18230fdc8d8SChris Lattner             {
18330fdc8d8SChris Lattner             case 'f':  log_file = option_arg;                                 break;
18430fdc8d8SChris Lattner             case 't':  log_options |= LLDB_LOG_OPTION_THREADSAFE;             break;
18530fdc8d8SChris Lattner             case 'v':  log_options |= LLDB_LOG_OPTION_VERBOSE;                break;
18630fdc8d8SChris Lattner             case 'g':  log_options |= LLDB_LOG_OPTION_DEBUG;                  break;
18730fdc8d8SChris Lattner             case 's':  log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE;       break;
18830fdc8d8SChris Lattner             case 'T':  log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP;      break;
18930fdc8d8SChris Lattner             case 'p':  log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break;
19030fdc8d8SChris Lattner             case 'n':  log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME;    break;
19130fdc8d8SChris Lattner             default:
19230fdc8d8SChris Lattner                 error.SetErrorStringWithFormat ("Unrecognized option '%c'\n", short_option);
19330fdc8d8SChris Lattner                 break;
19430fdc8d8SChris Lattner             }
19530fdc8d8SChris Lattner 
19630fdc8d8SChris Lattner             return error;
19730fdc8d8SChris Lattner         }
19830fdc8d8SChris Lattner 
19930fdc8d8SChris Lattner         void
20030fdc8d8SChris Lattner         ResetOptionValues ()
20130fdc8d8SChris Lattner         {
20230fdc8d8SChris Lattner             Options::ResetOptionValues();
20330fdc8d8SChris Lattner             log_file.clear();
20430fdc8d8SChris Lattner             log_options = 0;
20530fdc8d8SChris Lattner         }
20630fdc8d8SChris Lattner 
20730fdc8d8SChris Lattner         const lldb::OptionDefinition*
20830fdc8d8SChris Lattner         GetDefinitions ()
20930fdc8d8SChris Lattner         {
21030fdc8d8SChris Lattner             return g_option_table;
21130fdc8d8SChris Lattner         }
21230fdc8d8SChris Lattner 
21330fdc8d8SChris Lattner         // Options table: Required for subclasses of Options.
21430fdc8d8SChris Lattner 
21530fdc8d8SChris Lattner         static lldb::OptionDefinition g_option_table[];
21630fdc8d8SChris Lattner 
21730fdc8d8SChris Lattner         // Instance variables to hold the values for command options.
21830fdc8d8SChris Lattner 
21930fdc8d8SChris Lattner         std::string log_file;
22030fdc8d8SChris Lattner         uint32_t log_options;
22130fdc8d8SChris Lattner     };
22230fdc8d8SChris Lattner 
22330fdc8d8SChris Lattner protected:
22430fdc8d8SChris Lattner     typedef std::map<std::string, StreamSP> LogStreamMap;
22530fdc8d8SChris Lattner     CommandOptions m_options;
22630fdc8d8SChris Lattner     LogStreamMap m_log_streams;
22730fdc8d8SChris Lattner };
22830fdc8d8SChris Lattner 
22930fdc8d8SChris Lattner lldb::OptionDefinition
23030fdc8d8SChris Lattner CommandObjectLogEnable::CommandOptions::g_option_table[] =
23130fdc8d8SChris Lattner {
232deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "file",       'f', required_argument, NULL, 0, eArgTypeFilename,   "Set the destination file to log to."},
233deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "threadsafe", 't', no_argument,       NULL, 0, eArgTypeNone,        "Enable thread safe logging to avoid interweaved log lines." },
234deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "verbose",    'v', no_argument,       NULL, 0, eArgTypeNone,       "Enable verbose logging." },
235deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "debug",      'g', no_argument,       NULL, 0, eArgTypeNone,       "Enable debug logging." },
236deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "sequence",   's', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with an increasing integer sequence id." },
237deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "timestamp",  'T', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with a timestamp." },
238deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "pid-tid",    'p', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with the process and thread ID that generates the log line." },
239deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "thread-name",'n', no_argument,       NULL, 0, eArgTypeNone,       "Prepend all log lines with the thread name for the thread that generates the log line." },
240deaab222SCaroline Tice { 0, false, NULL,                       0,  0,                 NULL, 0, eArgTypeNone,       NULL }
24130fdc8d8SChris Lattner };
24230fdc8d8SChris Lattner 
24330fdc8d8SChris Lattner class CommandObjectLogDisable : public CommandObject
24430fdc8d8SChris Lattner {
24530fdc8d8SChris Lattner public:
24630fdc8d8SChris Lattner     //------------------------------------------------------------------
24730fdc8d8SChris Lattner     // Constructors and Destructors
24830fdc8d8SChris Lattner     //------------------------------------------------------------------
249a7015092SGreg Clayton     CommandObjectLogDisable(CommandInterpreter &interpreter) :
250a7015092SGreg Clayton         CommandObject (interpreter,
251a7015092SGreg Clayton                        "log disable",
25230fdc8d8SChris Lattner                        "Disable one or more log channels.",
253*405fe67fSCaroline Tice                        NULL)
25430fdc8d8SChris Lattner     {
255*405fe67fSCaroline Tice         CommandArgumentEntry arg;
256*405fe67fSCaroline Tice         CommandArgumentData channel_arg;
257*405fe67fSCaroline Tice 
258*405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
259*405fe67fSCaroline Tice         channel_arg.arg_type = eArgTypeLogChannel;
260*405fe67fSCaroline Tice         channel_arg.arg_repetition = eArgRepeatPlus;
261*405fe67fSCaroline Tice 
262*405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
263*405fe67fSCaroline Tice         arg.push_back (channel_arg);
264*405fe67fSCaroline Tice 
265*405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
266*405fe67fSCaroline Tice         m_arguments.push_back (arg);
26730fdc8d8SChris Lattner     }
26830fdc8d8SChris Lattner 
26930fdc8d8SChris Lattner     virtual
27030fdc8d8SChris Lattner     ~CommandObjectLogDisable()
27130fdc8d8SChris Lattner     {
27230fdc8d8SChris Lattner     }
27330fdc8d8SChris Lattner 
27430fdc8d8SChris Lattner     virtual bool
275a7015092SGreg Clayton     Execute (Args& args,
27630fdc8d8SChris Lattner              CommandReturnObject &result)
27730fdc8d8SChris Lattner     {
27830fdc8d8SChris Lattner         const size_t argc = args.GetArgumentCount();
27930fdc8d8SChris Lattner         if (argc == 0)
28030fdc8d8SChris Lattner         {
281e3d26315SCaroline Tice             result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
28230fdc8d8SChris Lattner         }
28330fdc8d8SChris Lattner         else
28430fdc8d8SChris Lattner         {
28530fdc8d8SChris Lattner             for (size_t i=0; i<argc; ++i)
28630fdc8d8SChris Lattner             {
28730fdc8d8SChris Lattner                 Log::Callbacks log_callbacks;
28830fdc8d8SChris Lattner 
28930fdc8d8SChris Lattner                 std::string channel(args.GetArgumentAtIndex(i));
29030fdc8d8SChris Lattner                 if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
29130fdc8d8SChris Lattner                 {
29230fdc8d8SChris Lattner                     log_callbacks.disable ();
29330fdc8d8SChris Lattner                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
29430fdc8d8SChris Lattner                 }
29530fdc8d8SChris Lattner                 else if (channel == "all")
29630fdc8d8SChris Lattner                 {
29730fdc8d8SChris Lattner                     Log::DisableAllLogChannels();
29830fdc8d8SChris Lattner                 }
29930fdc8d8SChris Lattner                 else
30030fdc8d8SChris Lattner                 {
30130fdc8d8SChris Lattner                     LogChannelSP log_channel_sp (GetLogChannelPluginForChannel(channel.c_str()));
30230fdc8d8SChris Lattner                     if (log_channel_sp)
30330fdc8d8SChris Lattner                     {
30430fdc8d8SChris Lattner                         log_channel_sp->Disable();
30530fdc8d8SChris Lattner                         result.SetStatus(eReturnStatusSuccessFinishNoResult);
30630fdc8d8SChris Lattner                     }
30730fdc8d8SChris Lattner                     else
30830fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
30930fdc8d8SChris Lattner                 }
31030fdc8d8SChris Lattner             }
31130fdc8d8SChris Lattner         }
31230fdc8d8SChris Lattner         return result.Succeeded();
31330fdc8d8SChris Lattner     }
31430fdc8d8SChris Lattner };
31530fdc8d8SChris Lattner 
31630fdc8d8SChris Lattner class CommandObjectLogList : public CommandObject
31730fdc8d8SChris Lattner {
31830fdc8d8SChris Lattner public:
31930fdc8d8SChris Lattner     //------------------------------------------------------------------
32030fdc8d8SChris Lattner     // Constructors and Destructors
32130fdc8d8SChris Lattner     //------------------------------------------------------------------
322a7015092SGreg Clayton     CommandObjectLogList(CommandInterpreter &interpreter) :
323a7015092SGreg Clayton         CommandObject (interpreter,
324a7015092SGreg Clayton                        "log list",
325*405fe67fSCaroline Tice                        "List the log categories for one or more log channels.  If none specified, lists them all.",
326*405fe67fSCaroline Tice                        NULL)
32730fdc8d8SChris Lattner     {
328*405fe67fSCaroline Tice         CommandArgumentEntry arg;
329*405fe67fSCaroline Tice         CommandArgumentData channel_arg;
330*405fe67fSCaroline Tice 
331*405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
332*405fe67fSCaroline Tice         channel_arg.arg_type = eArgTypeLogChannel;
333*405fe67fSCaroline Tice         channel_arg.arg_repetition = eArgRepeatStar;
334*405fe67fSCaroline Tice 
335*405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
336*405fe67fSCaroline Tice         arg.push_back (channel_arg);
337*405fe67fSCaroline Tice 
338*405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
339*405fe67fSCaroline Tice         m_arguments.push_back (arg);
34030fdc8d8SChris Lattner     }
34130fdc8d8SChris Lattner 
34230fdc8d8SChris Lattner     virtual
34330fdc8d8SChris Lattner     ~CommandObjectLogList()
34430fdc8d8SChris Lattner     {
34530fdc8d8SChris Lattner     }
34630fdc8d8SChris Lattner 
34730fdc8d8SChris Lattner     virtual bool
348a7015092SGreg Clayton     Execute (Args& args,
34930fdc8d8SChris Lattner              CommandReturnObject &result)
35030fdc8d8SChris Lattner     {
35130fdc8d8SChris Lattner         const size_t argc = args.GetArgumentCount();
35230fdc8d8SChris Lattner         if (argc == 0)
35330fdc8d8SChris Lattner         {
35430fdc8d8SChris Lattner             Log::ListAllLogChannels (&result.GetOutputStream());
35530fdc8d8SChris Lattner             result.SetStatus(eReturnStatusSuccessFinishResult);
35630fdc8d8SChris Lattner         }
35730fdc8d8SChris Lattner         else
35830fdc8d8SChris Lattner         {
35930fdc8d8SChris Lattner             for (size_t i=0; i<argc; ++i)
36030fdc8d8SChris Lattner             {
36130fdc8d8SChris Lattner                 Log::Callbacks log_callbacks;
36230fdc8d8SChris Lattner 
36330fdc8d8SChris Lattner                 std::string channel(args.GetArgumentAtIndex(i));
36430fdc8d8SChris Lattner                 if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks))
36530fdc8d8SChris Lattner                 {
36630fdc8d8SChris Lattner                     log_callbacks.list_categories (&result.GetOutputStream());
36730fdc8d8SChris Lattner                     result.SetStatus(eReturnStatusSuccessFinishResult);
36830fdc8d8SChris Lattner                 }
36930fdc8d8SChris Lattner                 else if (channel == "all")
37030fdc8d8SChris Lattner                 {
37130fdc8d8SChris Lattner                     Log::ListAllLogChannels (&result.GetOutputStream());
37230fdc8d8SChris Lattner                     result.SetStatus(eReturnStatusSuccessFinishResult);
37330fdc8d8SChris Lattner                 }
37430fdc8d8SChris Lattner                 else
37530fdc8d8SChris Lattner                 {
37630fdc8d8SChris Lattner                     LogChannelSP log_channel_sp (GetLogChannelPluginForChannel(channel.c_str()));
37730fdc8d8SChris Lattner                     if (log_channel_sp)
37830fdc8d8SChris Lattner                     {
37930fdc8d8SChris Lattner                         log_channel_sp->ListCategories(&result.GetOutputStream());
38030fdc8d8SChris Lattner                         result.SetStatus(eReturnStatusSuccessFinishNoResult);
38130fdc8d8SChris Lattner                     }
38230fdc8d8SChris Lattner                     else
38330fdc8d8SChris Lattner                         result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0));
38430fdc8d8SChris Lattner                 }
38530fdc8d8SChris Lattner             }
38630fdc8d8SChris Lattner         }
38730fdc8d8SChris Lattner         return result.Succeeded();
38830fdc8d8SChris Lattner     }
38930fdc8d8SChris Lattner };
39030fdc8d8SChris Lattner 
39130fdc8d8SChris Lattner class CommandObjectLogTimer : public CommandObject
39230fdc8d8SChris Lattner {
39330fdc8d8SChris Lattner public:
39430fdc8d8SChris Lattner     //------------------------------------------------------------------
39530fdc8d8SChris Lattner     // Constructors and Destructors
39630fdc8d8SChris Lattner     //------------------------------------------------------------------
397a7015092SGreg Clayton     CommandObjectLogTimer(CommandInterpreter &interpreter) :
398a7015092SGreg Clayton         CommandObject (interpreter,
399a7015092SGreg Clayton                        "log timers",
40030fdc8d8SChris Lattner                        "Enable, disable, dump, and reset LLDB internal performance timers.",
40130fdc8d8SChris Lattner                        "log timers < enable | disable | dump | reset >")
40230fdc8d8SChris Lattner     {
40330fdc8d8SChris Lattner     }
40430fdc8d8SChris Lattner 
40530fdc8d8SChris Lattner     virtual
40630fdc8d8SChris Lattner     ~CommandObjectLogTimer()
40730fdc8d8SChris Lattner     {
40830fdc8d8SChris Lattner     }
40930fdc8d8SChris Lattner 
41030fdc8d8SChris Lattner     virtual bool
411a7015092SGreg Clayton     Execute (Args& args,
41230fdc8d8SChris Lattner              CommandReturnObject &result)
41330fdc8d8SChris Lattner     {
41430fdc8d8SChris Lattner         const size_t argc = args.GetArgumentCount();
41530fdc8d8SChris Lattner         result.SetStatus(eReturnStatusFailed);
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner         if (argc == 1)
41830fdc8d8SChris Lattner         {
41930fdc8d8SChris Lattner             const char *sub_command = args.GetArgumentAtIndex(0);
42030fdc8d8SChris Lattner 
42130fdc8d8SChris Lattner             if (strcasecmp(sub_command, "enable") == 0)
42230fdc8d8SChris Lattner             {
42330fdc8d8SChris Lattner                 Timer::SetDisplayDepth (UINT32_MAX);
42430fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishNoResult);
42530fdc8d8SChris Lattner             }
42630fdc8d8SChris Lattner             else if (strcasecmp(sub_command, "disable") == 0)
42730fdc8d8SChris Lattner             {
42830fdc8d8SChris Lattner                 Timer::DumpCategoryTimes (&result.GetOutputStream());
42930fdc8d8SChris Lattner                 Timer::SetDisplayDepth (0);
43030fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishResult);
43130fdc8d8SChris Lattner             }
43230fdc8d8SChris Lattner             else if (strcasecmp(sub_command, "dump") == 0)
43330fdc8d8SChris Lattner             {
43430fdc8d8SChris Lattner                 Timer::DumpCategoryTimes (&result.GetOutputStream());
43530fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishResult);
43630fdc8d8SChris Lattner             }
43730fdc8d8SChris Lattner             else if (strcasecmp(sub_command, "reset") == 0)
43830fdc8d8SChris Lattner             {
43930fdc8d8SChris Lattner                 Timer::ResetCategoryTimes ();
44030fdc8d8SChris Lattner                 result.SetStatus(eReturnStatusSuccessFinishResult);
44130fdc8d8SChris Lattner             }
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner         }
44430fdc8d8SChris Lattner         if (!result.Succeeded())
44530fdc8d8SChris Lattner         {
44630fdc8d8SChris Lattner             result.AppendError("Missing subcommand");
44730fdc8d8SChris Lattner             result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
44830fdc8d8SChris Lattner         }
44930fdc8d8SChris Lattner         return result.Succeeded();
45030fdc8d8SChris Lattner     }
45130fdc8d8SChris Lattner };
45230fdc8d8SChris Lattner 
45330fdc8d8SChris Lattner //----------------------------------------------------------------------
45430fdc8d8SChris Lattner // CommandObjectLog constructor
45530fdc8d8SChris Lattner //----------------------------------------------------------------------
4566611103cSGreg Clayton CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) :
457a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
458a7015092SGreg Clayton                             "log",
45930fdc8d8SChris Lattner                             "A set of commands for operating on logs.",
46030fdc8d8SChris Lattner                             "log <command> [<command-options>]")
46130fdc8d8SChris Lattner {
462a7015092SGreg Clayton     LoadSubCommand ("enable",  CommandObjectSP (new CommandObjectLogEnable (interpreter)));
463a7015092SGreg Clayton     LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter)));
464a7015092SGreg Clayton     LoadSubCommand ("list",    CommandObjectSP (new CommandObjectLogList (interpreter)));
465a7015092SGreg Clayton     LoadSubCommand ("timers",  CommandObjectSP (new CommandObjectLogTimer (interpreter)));
46630fdc8d8SChris Lattner }
46730fdc8d8SChris Lattner 
46830fdc8d8SChris Lattner //----------------------------------------------------------------------
46930fdc8d8SChris Lattner // Destructor
47030fdc8d8SChris Lattner //----------------------------------------------------------------------
47130fdc8d8SChris Lattner CommandObjectLog::~CommandObjectLog()
47230fdc8d8SChris Lattner {
47330fdc8d8SChris Lattner }
47430fdc8d8SChris Lattner 
47530fdc8d8SChris Lattner 
47630fdc8d8SChris Lattner 
47730fdc8d8SChris Lattner 
478