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" 2053239f00SGreg Clayton #include "lldb/Host/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 class CommandObjectLogEnable : public CommandObject 4630fdc8d8SChris Lattner { 4730fdc8d8SChris Lattner public: 4830fdc8d8SChris Lattner //------------------------------------------------------------------ 4930fdc8d8SChris Lattner // Constructors and Destructors 5030fdc8d8SChris Lattner //------------------------------------------------------------------ 51a7015092SGreg Clayton CommandObjectLogEnable(CommandInterpreter &interpreter) : 52a7015092SGreg Clayton CommandObject (interpreter, 53a7015092SGreg Clayton "log enable", 5430fdc8d8SChris Lattner "Enable logging for a single log channel.", 55eb0103f2SGreg Clayton NULL), 56eb0103f2SGreg Clayton m_options (interpreter) 5730fdc8d8SChris Lattner { 58ceb6b139SCaroline Tice 59ceb6b139SCaroline Tice CommandArgumentEntry arg1; 60ceb6b139SCaroline Tice CommandArgumentEntry arg2; 61405fe67fSCaroline Tice CommandArgumentData channel_arg; 62ceb6b139SCaroline Tice CommandArgumentData category_arg; 63405fe67fSCaroline Tice 64405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 65405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 66405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 67405fe67fSCaroline Tice 68405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 69ceb6b139SCaroline Tice arg1.push_back (channel_arg); 70ceb6b139SCaroline Tice 71ceb6b139SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 72ceb6b139SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 73ceb6b139SCaroline Tice 74ceb6b139SCaroline Tice arg2.push_back (category_arg); 75405fe67fSCaroline Tice 76405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 77ceb6b139SCaroline Tice m_arguments.push_back (arg1); 78ceb6b139SCaroline Tice m_arguments.push_back (arg2); 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 92ab65b34fSGreg Clayton // int 93ab65b34fSGreg Clayton // HandleArgumentCompletion (Args &input, 94ab65b34fSGreg Clayton // int &cursor_index, 95ab65b34fSGreg Clayton // int &cursor_char_position, 96ab65b34fSGreg Clayton // OptionElementVector &opt_element_vector, 97ab65b34fSGreg Clayton // int match_start_point, 98ab65b34fSGreg Clayton // int max_return_elements, 99ab65b34fSGreg Clayton // bool &word_complete, 100ab65b34fSGreg Clayton // StringList &matches) 101ab65b34fSGreg Clayton // { 102ab65b34fSGreg Clayton // std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 103ab65b34fSGreg Clayton // completion_str.erase (cursor_char_position); 104ab65b34fSGreg Clayton // 105ab65b34fSGreg Clayton // if (cursor_index == 1) 106ab65b34fSGreg Clayton // { 107ab65b34fSGreg Clayton // // 108ab65b34fSGreg Clayton // Log::AutoCompleteChannelName (completion_str.c_str(), matches); 109ab65b34fSGreg Clayton // } 110ab65b34fSGreg Clayton // return matches.GetSize(); 111ab65b34fSGreg Clayton // } 112ab65b34fSGreg Clayton // 11330fdc8d8SChris Lattner virtual bool 114a7015092SGreg Clayton Execute (Args& args, 11530fdc8d8SChris Lattner CommandReturnObject &result) 11630fdc8d8SChris Lattner { 11730fdc8d8SChris Lattner if (args.GetArgumentCount() < 1) 11830fdc8d8SChris Lattner { 119e3d26315SCaroline Tice result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 12030fdc8d8SChris Lattner } 12130fdc8d8SChris Lattner else 12230fdc8d8SChris Lattner { 12330fdc8d8SChris Lattner Log::Callbacks log_callbacks; 12430fdc8d8SChris Lattner 12530fdc8d8SChris Lattner std::string channel(args.GetArgumentAtIndex(0)); 12630fdc8d8SChris Lattner args.Shift (); // Shift off the channel 12730fdc8d8SChris Lattner StreamSP log_stream_sp; 12830fdc8d8SChris Lattner if (m_options.log_file.empty()) 12930fdc8d8SChris Lattner { 13051b1e2d2SGreg Clayton log_stream_sp.reset(new StreamFile(m_interpreter.GetDebugger().GetOutputFile().GetDescriptor(), false)); 13130fdc8d8SChris Lattner } 13230fdc8d8SChris Lattner else 13330fdc8d8SChris Lattner { 13430fdc8d8SChris Lattner LogStreamMap::iterator pos = m_log_streams.find(m_options.log_file); 13530fdc8d8SChris Lattner if (pos == m_log_streams.end()) 13630fdc8d8SChris Lattner { 13751b1e2d2SGreg Clayton log_stream_sp.reset (new StreamFile (m_options.log_file.c_str())); 13830fdc8d8SChris Lattner m_log_streams[m_options.log_file] = log_stream_sp; 13930fdc8d8SChris Lattner } 14030fdc8d8SChris Lattner else 14130fdc8d8SChris Lattner log_stream_sp = pos->second; 14230fdc8d8SChris Lattner } 14330fdc8d8SChris Lattner assert (log_stream_sp.get()); 1449f35921bSJim Ingham 14530fdc8d8SChris Lattner uint32_t log_options = m_options.log_options; 14630fdc8d8SChris Lattner if (log_options == 0) 14730fdc8d8SChris Lattner log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE; 14830fdc8d8SChris Lattner if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks)) 14930fdc8d8SChris Lattner { 15030fdc8d8SChris Lattner log_callbacks.enable (log_stream_sp, log_options, args, &result.GetErrorStream()); 15130fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 15230fdc8d8SChris Lattner } 15330fdc8d8SChris Lattner else 15430fdc8d8SChris Lattner { 155ab65b34fSGreg Clayton LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel.c_str())); 15630fdc8d8SChris Lattner if (log_channel_sp) 15730fdc8d8SChris Lattner { 15830fdc8d8SChris Lattner if (log_channel_sp->Enable (log_stream_sp, log_options, &result.GetErrorStream(), args)) 15930fdc8d8SChris Lattner { 16030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 16130fdc8d8SChris Lattner } 16230fdc8d8SChris Lattner else 16330fdc8d8SChris Lattner { 16430fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str()); 16530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 16630fdc8d8SChris Lattner } 16730fdc8d8SChris Lattner } 16830fdc8d8SChris Lattner else 16930fdc8d8SChris Lattner { 17030fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", channel.c_str()); 17130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 17230fdc8d8SChris Lattner } 17330fdc8d8SChris Lattner } 17430fdc8d8SChris Lattner } 17530fdc8d8SChris Lattner return result.Succeeded(); 17630fdc8d8SChris Lattner } 17730fdc8d8SChris Lattner 17830fdc8d8SChris Lattner 17930fdc8d8SChris Lattner class CommandOptions : public Options 18030fdc8d8SChris Lattner { 18130fdc8d8SChris Lattner public: 18230fdc8d8SChris Lattner 183eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 184eb0103f2SGreg Clayton Options (interpreter), 18530fdc8d8SChris Lattner log_file (), 18630fdc8d8SChris Lattner log_options (0) 18730fdc8d8SChris Lattner { 18830fdc8d8SChris Lattner } 18930fdc8d8SChris Lattner 19030fdc8d8SChris Lattner 19130fdc8d8SChris Lattner virtual 19230fdc8d8SChris Lattner ~CommandOptions () 19330fdc8d8SChris Lattner { 19430fdc8d8SChris Lattner } 19530fdc8d8SChris Lattner 19630fdc8d8SChris Lattner virtual Error 197f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 19830fdc8d8SChris Lattner { 19930fdc8d8SChris Lattner Error error; 20030fdc8d8SChris Lattner char short_option = (char) m_getopt_table[option_idx].val; 20130fdc8d8SChris Lattner 20230fdc8d8SChris Lattner switch (short_option) 20330fdc8d8SChris Lattner { 20430fdc8d8SChris Lattner case 'f': log_file = option_arg; break; 20530fdc8d8SChris Lattner case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; break; 20630fdc8d8SChris Lattner case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break; 20730fdc8d8SChris Lattner case 'g': log_options |= LLDB_LOG_OPTION_DEBUG; break; 20830fdc8d8SChris Lattner case 's': log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; break; 20930fdc8d8SChris Lattner case 'T': log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; break; 21030fdc8d8SChris Lattner case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break; 21130fdc8d8SChris Lattner case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break; 21230fdc8d8SChris Lattner default: 213*86edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 21430fdc8d8SChris Lattner break; 21530fdc8d8SChris Lattner } 21630fdc8d8SChris Lattner 21730fdc8d8SChris Lattner return error; 21830fdc8d8SChris Lattner } 21930fdc8d8SChris Lattner 22030fdc8d8SChris Lattner void 221f6b8b581SGreg Clayton OptionParsingStarting () 22230fdc8d8SChris Lattner { 22330fdc8d8SChris Lattner log_file.clear(); 22430fdc8d8SChris Lattner log_options = 0; 22530fdc8d8SChris Lattner } 22630fdc8d8SChris Lattner 227e0d378b3SGreg Clayton const OptionDefinition* 22830fdc8d8SChris Lattner GetDefinitions () 22930fdc8d8SChris Lattner { 23030fdc8d8SChris Lattner return g_option_table; 23130fdc8d8SChris Lattner } 23230fdc8d8SChris Lattner 23330fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 23430fdc8d8SChris Lattner 235e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 23630fdc8d8SChris Lattner 23730fdc8d8SChris Lattner // Instance variables to hold the values for command options. 23830fdc8d8SChris Lattner 23930fdc8d8SChris Lattner std::string log_file; 24030fdc8d8SChris Lattner uint32_t log_options; 24130fdc8d8SChris Lattner }; 24230fdc8d8SChris Lattner 24330fdc8d8SChris Lattner protected: 24430fdc8d8SChris Lattner typedef std::map<std::string, StreamSP> LogStreamMap; 24530fdc8d8SChris Lattner CommandOptions m_options; 24630fdc8d8SChris Lattner LogStreamMap m_log_streams; 24730fdc8d8SChris Lattner }; 24830fdc8d8SChris Lattner 249e0d378b3SGreg Clayton OptionDefinition 25030fdc8d8SChris Lattner CommandObjectLogEnable::CommandOptions::g_option_table[] = 25130fdc8d8SChris Lattner { 252deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Set the destination file to log to."}, 253deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "threadsafe", 't', no_argument, NULL, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, 254deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose logging." }, 255deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable debug logging." }, 256deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "sequence", 's', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, 257deaab222SCaroline Tice { LLDB_OPT_SET_1, false, "timestamp", 'T', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, 258deaab222SCaroline 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." }, 259deaab222SCaroline 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." }, 260deaab222SCaroline Tice { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 26130fdc8d8SChris Lattner }; 26230fdc8d8SChris Lattner 26330fdc8d8SChris Lattner class CommandObjectLogDisable : public CommandObject 26430fdc8d8SChris Lattner { 26530fdc8d8SChris Lattner public: 26630fdc8d8SChris Lattner //------------------------------------------------------------------ 26730fdc8d8SChris Lattner // Constructors and Destructors 26830fdc8d8SChris Lattner //------------------------------------------------------------------ 269a7015092SGreg Clayton CommandObjectLogDisable(CommandInterpreter &interpreter) : 270a7015092SGreg Clayton CommandObject (interpreter, 271a7015092SGreg Clayton "log disable", 2727149fab4SCaroline Tice "Disable one or more log channel categories.", 273405fe67fSCaroline Tice NULL) 27430fdc8d8SChris Lattner { 2757149fab4SCaroline Tice CommandArgumentEntry arg1; 2767149fab4SCaroline Tice CommandArgumentEntry arg2; 277405fe67fSCaroline Tice CommandArgumentData channel_arg; 2787149fab4SCaroline Tice CommandArgumentData category_arg; 279405fe67fSCaroline Tice 280405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 281405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 2827149fab4SCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 283405fe67fSCaroline Tice 284405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 2857149fab4SCaroline Tice arg1.push_back (channel_arg); 2867149fab4SCaroline Tice 2877149fab4SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 2887149fab4SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 2897149fab4SCaroline Tice 2907149fab4SCaroline Tice arg2.push_back (category_arg); 291405fe67fSCaroline Tice 292405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 2937149fab4SCaroline Tice m_arguments.push_back (arg1); 2947149fab4SCaroline Tice m_arguments.push_back (arg2); 29530fdc8d8SChris Lattner } 29630fdc8d8SChris Lattner 29730fdc8d8SChris Lattner virtual 29830fdc8d8SChris Lattner ~CommandObjectLogDisable() 29930fdc8d8SChris Lattner { 30030fdc8d8SChris Lattner } 30130fdc8d8SChris Lattner 30230fdc8d8SChris Lattner virtual bool 303a7015092SGreg Clayton Execute (Args& args, 30430fdc8d8SChris Lattner CommandReturnObject &result) 30530fdc8d8SChris Lattner { 30630fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 30730fdc8d8SChris Lattner if (argc == 0) 30830fdc8d8SChris Lattner { 309e3d26315SCaroline Tice result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 31030fdc8d8SChris Lattner } 31130fdc8d8SChris Lattner else 31230fdc8d8SChris Lattner { 31330fdc8d8SChris Lattner Log::Callbacks log_callbacks; 31430fdc8d8SChris Lattner 31520ad3c40SCaroline Tice std::string channel(args.GetArgumentAtIndex(0)); 31620ad3c40SCaroline Tice args.Shift (); // Shift off the channel 31730fdc8d8SChris Lattner if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks)) 31830fdc8d8SChris Lattner { 31920ad3c40SCaroline Tice log_callbacks.disable (args, &result.GetErrorStream()); 32030fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 32130fdc8d8SChris Lattner } 32230fdc8d8SChris Lattner else if (channel == "all") 32330fdc8d8SChris Lattner { 32420ad3c40SCaroline Tice Log::DisableAllLogChannels(&result.GetErrorStream()); 32530fdc8d8SChris Lattner } 32630fdc8d8SChris Lattner else 32730fdc8d8SChris Lattner { 328ab65b34fSGreg Clayton LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str())); 32930fdc8d8SChris Lattner if (log_channel_sp) 33030fdc8d8SChris Lattner { 33120ad3c40SCaroline Tice log_channel_sp->Disable(args, &result.GetErrorStream()); 33230fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 33330fdc8d8SChris Lattner } 33430fdc8d8SChris Lattner else 33530fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0)); 33630fdc8d8SChris Lattner } 33730fdc8d8SChris Lattner } 33830fdc8d8SChris Lattner return result.Succeeded(); 33930fdc8d8SChris Lattner } 34030fdc8d8SChris Lattner }; 34130fdc8d8SChris Lattner 34230fdc8d8SChris Lattner class CommandObjectLogList : public CommandObject 34330fdc8d8SChris Lattner { 34430fdc8d8SChris Lattner public: 34530fdc8d8SChris Lattner //------------------------------------------------------------------ 34630fdc8d8SChris Lattner // Constructors and Destructors 34730fdc8d8SChris Lattner //------------------------------------------------------------------ 348a7015092SGreg Clayton CommandObjectLogList(CommandInterpreter &interpreter) : 349a7015092SGreg Clayton CommandObject (interpreter, 350a7015092SGreg Clayton "log list", 351405fe67fSCaroline Tice "List the log categories for one or more log channels. If none specified, lists them all.", 352405fe67fSCaroline Tice NULL) 35330fdc8d8SChris Lattner { 354405fe67fSCaroline Tice CommandArgumentEntry arg; 355405fe67fSCaroline Tice CommandArgumentData channel_arg; 356405fe67fSCaroline Tice 357405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 358405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 359405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatStar; 360405fe67fSCaroline Tice 361405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 362405fe67fSCaroline Tice arg.push_back (channel_arg); 363405fe67fSCaroline Tice 364405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 365405fe67fSCaroline Tice m_arguments.push_back (arg); 36630fdc8d8SChris Lattner } 36730fdc8d8SChris Lattner 36830fdc8d8SChris Lattner virtual 36930fdc8d8SChris Lattner ~CommandObjectLogList() 37030fdc8d8SChris Lattner { 37130fdc8d8SChris Lattner } 37230fdc8d8SChris Lattner 37330fdc8d8SChris Lattner virtual bool 374a7015092SGreg Clayton Execute (Args& args, 37530fdc8d8SChris Lattner CommandReturnObject &result) 37630fdc8d8SChris Lattner { 37730fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 37830fdc8d8SChris Lattner if (argc == 0) 37930fdc8d8SChris Lattner { 38030fdc8d8SChris Lattner Log::ListAllLogChannels (&result.GetOutputStream()); 38130fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 38230fdc8d8SChris Lattner } 38330fdc8d8SChris Lattner else 38430fdc8d8SChris Lattner { 38530fdc8d8SChris Lattner for (size_t i=0; i<argc; ++i) 38630fdc8d8SChris Lattner { 38730fdc8d8SChris Lattner Log::Callbacks log_callbacks; 38830fdc8d8SChris Lattner 38930fdc8d8SChris Lattner std::string channel(args.GetArgumentAtIndex(i)); 39030fdc8d8SChris Lattner if (Log::GetLogChannelCallbacks (channel.c_str(), log_callbacks)) 39130fdc8d8SChris Lattner { 39230fdc8d8SChris Lattner log_callbacks.list_categories (&result.GetOutputStream()); 39330fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 39430fdc8d8SChris Lattner } 39530fdc8d8SChris Lattner else if (channel == "all") 39630fdc8d8SChris Lattner { 39730fdc8d8SChris Lattner Log::ListAllLogChannels (&result.GetOutputStream()); 39830fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 39930fdc8d8SChris Lattner } 40030fdc8d8SChris Lattner else 40130fdc8d8SChris Lattner { 402ab65b34fSGreg Clayton LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str())); 40330fdc8d8SChris Lattner if (log_channel_sp) 40430fdc8d8SChris Lattner { 40530fdc8d8SChris Lattner log_channel_sp->ListCategories(&result.GetOutputStream()); 40630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 40730fdc8d8SChris Lattner } 40830fdc8d8SChris Lattner else 40930fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0)); 41030fdc8d8SChris Lattner } 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner } 41330fdc8d8SChris Lattner return result.Succeeded(); 41430fdc8d8SChris Lattner } 41530fdc8d8SChris Lattner }; 41630fdc8d8SChris Lattner 41730fdc8d8SChris Lattner class CommandObjectLogTimer : public CommandObject 41830fdc8d8SChris Lattner { 41930fdc8d8SChris Lattner public: 42030fdc8d8SChris Lattner //------------------------------------------------------------------ 42130fdc8d8SChris Lattner // Constructors and Destructors 42230fdc8d8SChris Lattner //------------------------------------------------------------------ 423a7015092SGreg Clayton CommandObjectLogTimer(CommandInterpreter &interpreter) : 424a7015092SGreg Clayton CommandObject (interpreter, 425a7015092SGreg Clayton "log timers", 42630fdc8d8SChris Lattner "Enable, disable, dump, and reset LLDB internal performance timers.", 427f7f4f501SJim Ingham "log timers < enable <depth> | disable | dump | increment <bool> | reset >") 42830fdc8d8SChris Lattner { 42930fdc8d8SChris Lattner } 43030fdc8d8SChris Lattner 43130fdc8d8SChris Lattner virtual 43230fdc8d8SChris Lattner ~CommandObjectLogTimer() 43330fdc8d8SChris Lattner { 43430fdc8d8SChris Lattner } 43530fdc8d8SChris Lattner 43630fdc8d8SChris Lattner virtual bool 437a7015092SGreg Clayton Execute (Args& args, 43830fdc8d8SChris Lattner CommandReturnObject &result) 43930fdc8d8SChris Lattner { 44030fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 44130fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 44230fdc8d8SChris Lattner 44330fdc8d8SChris Lattner if (argc == 1) 44430fdc8d8SChris Lattner { 44530fdc8d8SChris Lattner const char *sub_command = args.GetArgumentAtIndex(0); 44630fdc8d8SChris Lattner 44730fdc8d8SChris Lattner if (strcasecmp(sub_command, "enable") == 0) 44830fdc8d8SChris Lattner { 44930fdc8d8SChris Lattner Timer::SetDisplayDepth (UINT32_MAX); 45030fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner else if (strcasecmp(sub_command, "disable") == 0) 45330fdc8d8SChris Lattner { 45430fdc8d8SChris Lattner Timer::DumpCategoryTimes (&result.GetOutputStream()); 45530fdc8d8SChris Lattner Timer::SetDisplayDepth (0); 45630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 45730fdc8d8SChris Lattner } 45830fdc8d8SChris Lattner else if (strcasecmp(sub_command, "dump") == 0) 45930fdc8d8SChris Lattner { 46030fdc8d8SChris Lattner Timer::DumpCategoryTimes (&result.GetOutputStream()); 46130fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 46230fdc8d8SChris Lattner } 46330fdc8d8SChris Lattner else if (strcasecmp(sub_command, "reset") == 0) 46430fdc8d8SChris Lattner { 46530fdc8d8SChris Lattner Timer::ResetCategoryTimes (); 46630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 46730fdc8d8SChris Lattner } 46830fdc8d8SChris Lattner 46930fdc8d8SChris Lattner } 470932725faSJim Ingham else if (argc == 2) 471932725faSJim Ingham { 472932725faSJim Ingham const char *sub_command = args.GetArgumentAtIndex(0); 473932725faSJim Ingham 474932725faSJim Ingham if (strcasecmp(sub_command, "enable") == 0) 475932725faSJim Ingham { 476932725faSJim Ingham bool success; 477932725faSJim Ingham uint32_t depth = Args::StringToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success); 478932725faSJim Ingham if (success) 479932725faSJim Ingham { 480932725faSJim Ingham Timer::SetDisplayDepth (depth); 481932725faSJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 482932725faSJim Ingham } 483932725faSJim Ingham else 484932725faSJim Ingham result.AppendError("Could not convert enable depth to an unsigned integer."); 485932725faSJim Ingham } 486f7f4f501SJim Ingham if (strcasecmp(sub_command, "increment") == 0) 487f7f4f501SJim Ingham { 488f7f4f501SJim Ingham bool success; 489f7f4f501SJim Ingham bool increment = Args::StringToBoolean(args.GetArgumentAtIndex(1), false, &success); 490f7f4f501SJim Ingham if (success) 491f7f4f501SJim Ingham { 492f7f4f501SJim Ingham Timer::SetQuiet (!increment); 493f7f4f501SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 494f7f4f501SJim Ingham } 495f7f4f501SJim Ingham else 496f7f4f501SJim Ingham result.AppendError("Could not convert increment value to boolean."); 497f7f4f501SJim Ingham } 498932725faSJim Ingham } 499932725faSJim Ingham 50030fdc8d8SChris Lattner if (!result.Succeeded()) 50130fdc8d8SChris Lattner { 50230fdc8d8SChris Lattner result.AppendError("Missing subcommand"); 50330fdc8d8SChris Lattner result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 50430fdc8d8SChris Lattner } 50530fdc8d8SChris Lattner return result.Succeeded(); 50630fdc8d8SChris Lattner } 50730fdc8d8SChris Lattner }; 50830fdc8d8SChris Lattner 50930fdc8d8SChris Lattner //---------------------------------------------------------------------- 51030fdc8d8SChris Lattner // CommandObjectLog constructor 51130fdc8d8SChris Lattner //---------------------------------------------------------------------- 5126611103cSGreg Clayton CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) : 513a7015092SGreg Clayton CommandObjectMultiword (interpreter, 514a7015092SGreg Clayton "log", 51530fdc8d8SChris Lattner "A set of commands for operating on logs.", 51630fdc8d8SChris Lattner "log <command> [<command-options>]") 51730fdc8d8SChris Lattner { 518a7015092SGreg Clayton LoadSubCommand ("enable", CommandObjectSP (new CommandObjectLogEnable (interpreter))); 519a7015092SGreg Clayton LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter))); 520a7015092SGreg Clayton LoadSubCommand ("list", CommandObjectSP (new CommandObjectLogList (interpreter))); 521a7015092SGreg Clayton LoadSubCommand ("timers", CommandObjectSP (new CommandObjectLogTimer (interpreter))); 52230fdc8d8SChris Lattner } 52330fdc8d8SChris Lattner 52430fdc8d8SChris Lattner //---------------------------------------------------------------------- 52530fdc8d8SChris Lattner // Destructor 52630fdc8d8SChris Lattner //---------------------------------------------------------------------- 52730fdc8d8SChris Lattner CommandObjectLog::~CommandObjectLog() 52830fdc8d8SChris Lattner { 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner 53130fdc8d8SChris Lattner 53230fdc8d8SChris Lattner 53330fdc8d8SChris Lattner 534