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 // C Includes 1130fdc8d8SChris Lattner // C++ Includes 1230fdc8d8SChris Lattner // Other libraries and framework includes 1330fdc8d8SChris Lattner // Project includes 14*26cac3afSEugene Zelenko #include "CommandObjectLog.h" 1540af72e1SJim Ingham #include "lldb/Interpreter/Args.h" 1630fdc8d8SChris Lattner #include "lldb/Core/Debugger.h" 1753239f00SGreg Clayton #include "lldb/Host/FileSpec.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Log.h" 1930fdc8d8SChris Lattner #include "lldb/Core/Module.h" 2040af72e1SJim Ingham #include "lldb/Interpreter/Options.h" 2130fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h" 2230fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 2330fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 2430fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 256611103cSGreg Clayton #include "lldb/Core/Debugger.h" 265275aaa0SVince Harron #include "lldb/Host/StringConvert.h" 274be3990fSSean Callanan #include "lldb/Interpreter/CommandInterpreter.h" 2830fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 2930fdc8d8SChris Lattner #include "lldb/Symbol/LineTable.h" 3030fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 3130fdc8d8SChris Lattner #include "lldb/Symbol/SymbolFile.h" 3230fdc8d8SChris Lattner #include "lldb/Symbol/SymbolVendor.h" 3330fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3430fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3530fdc8d8SChris Lattner 3630fdc8d8SChris Lattner using namespace lldb; 3730fdc8d8SChris Lattner using namespace lldb_private; 3830fdc8d8SChris Lattner 395a988416SJim Ingham class CommandObjectLogEnable : public CommandObjectParsed 4030fdc8d8SChris Lattner { 4130fdc8d8SChris Lattner public: 4230fdc8d8SChris Lattner //------------------------------------------------------------------ 4330fdc8d8SChris Lattner // Constructors and Destructors 4430fdc8d8SChris Lattner //------------------------------------------------------------------ 45a7015092SGreg Clayton CommandObjectLogEnable(CommandInterpreter &interpreter) : 465a988416SJim Ingham CommandObjectParsed(interpreter, 47a7015092SGreg Clayton "log enable", 4830fdc8d8SChris Lattner "Enable logging for a single log channel.", 49*26cac3afSEugene Zelenko nullptr), 50eb0103f2SGreg Clayton m_options (interpreter) 5130fdc8d8SChris Lattner { 52ceb6b139SCaroline Tice CommandArgumentEntry arg1; 53ceb6b139SCaroline Tice CommandArgumentEntry arg2; 54405fe67fSCaroline Tice CommandArgumentData channel_arg; 55ceb6b139SCaroline Tice CommandArgumentData category_arg; 56405fe67fSCaroline Tice 57405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 58405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 59405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 60405fe67fSCaroline Tice 61405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 62ceb6b139SCaroline Tice arg1.push_back (channel_arg); 63ceb6b139SCaroline Tice 64ceb6b139SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 65ceb6b139SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 66ceb6b139SCaroline Tice 67ceb6b139SCaroline Tice arg2.push_back (category_arg); 68405fe67fSCaroline Tice 69405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 70ceb6b139SCaroline Tice m_arguments.push_back (arg1); 71ceb6b139SCaroline Tice m_arguments.push_back (arg2); 7230fdc8d8SChris Lattner } 7330fdc8d8SChris Lattner 74*26cac3afSEugene Zelenko ~CommandObjectLogEnable() override = default; 7530fdc8d8SChris Lattner 7630fdc8d8SChris Lattner Options * 7713d21e9aSBruce Mitchener GetOptions () override 7830fdc8d8SChris Lattner { 7930fdc8d8SChris Lattner return &m_options; 8030fdc8d8SChris Lattner } 8130fdc8d8SChris Lattner 82ab65b34fSGreg Clayton // int 83ab65b34fSGreg Clayton // HandleArgumentCompletion (Args &input, 84ab65b34fSGreg Clayton // int &cursor_index, 85ab65b34fSGreg Clayton // int &cursor_char_position, 86ab65b34fSGreg Clayton // OptionElementVector &opt_element_vector, 87ab65b34fSGreg Clayton // int match_start_point, 88ab65b34fSGreg Clayton // int max_return_elements, 89ab65b34fSGreg Clayton // bool &word_complete, 90ab65b34fSGreg Clayton // StringList &matches) 91ab65b34fSGreg Clayton // { 92ab65b34fSGreg Clayton // std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 93ab65b34fSGreg Clayton // completion_str.erase (cursor_char_position); 94ab65b34fSGreg Clayton // 95ab65b34fSGreg Clayton // if (cursor_index == 1) 96ab65b34fSGreg Clayton // { 97ab65b34fSGreg Clayton // // 98ab65b34fSGreg Clayton // Log::AutoCompleteChannelName (completion_str.c_str(), matches); 99ab65b34fSGreg Clayton // } 100ab65b34fSGreg Clayton // return matches.GetSize(); 101ab65b34fSGreg Clayton // } 102ab65b34fSGreg Clayton // 10330fdc8d8SChris Lattner 10430fdc8d8SChris Lattner class CommandOptions : public Options 10530fdc8d8SChris Lattner { 10630fdc8d8SChris Lattner public: 107eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 108eb0103f2SGreg Clayton Options (interpreter), 10930fdc8d8SChris Lattner log_file (), 11030fdc8d8SChris Lattner log_options (0) 11130fdc8d8SChris Lattner { 11230fdc8d8SChris Lattner } 11330fdc8d8SChris Lattner 114*26cac3afSEugene Zelenko ~CommandOptions () override = default; 11530fdc8d8SChris Lattner 11613d21e9aSBruce Mitchener Error 11713d21e9aSBruce Mitchener SetOptionValue (uint32_t option_idx, const char *option_arg) override 11830fdc8d8SChris Lattner { 11930fdc8d8SChris Lattner Error error; 1203bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12130fdc8d8SChris Lattner 12230fdc8d8SChris Lattner switch (short_option) 12330fdc8d8SChris Lattner { 124889037d7SGreg Clayton case 'f': log_file.SetFile(option_arg, true); break; 12530fdc8d8SChris Lattner case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; break; 12630fdc8d8SChris Lattner case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break; 12730fdc8d8SChris Lattner case 'g': log_options |= LLDB_LOG_OPTION_DEBUG; break; 12830fdc8d8SChris Lattner case 's': log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; break; 12930fdc8d8SChris Lattner case 'T': log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; break; 13030fdc8d8SChris Lattner case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break; 13130fdc8d8SChris Lattner case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break; 1323a18e319SGreg Clayton case 'S': log_options |= LLDB_LOG_OPTION_BACKTRACE; break; 1338ac06996SPavel Labath case 'a': log_options |= LLDB_LOG_OPTION_APPEND; break; 13430fdc8d8SChris Lattner default: 13586edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 13630fdc8d8SChris Lattner break; 13730fdc8d8SChris Lattner } 13830fdc8d8SChris Lattner 13930fdc8d8SChris Lattner return error; 14030fdc8d8SChris Lattner } 14130fdc8d8SChris Lattner 14230fdc8d8SChris Lattner void 14313d21e9aSBruce Mitchener OptionParsingStarting () override 14430fdc8d8SChris Lattner { 145889037d7SGreg Clayton log_file.Clear(); 14630fdc8d8SChris Lattner log_options = 0; 14730fdc8d8SChris Lattner } 14830fdc8d8SChris Lattner 149e0d378b3SGreg Clayton const OptionDefinition* 15013d21e9aSBruce Mitchener GetDefinitions () override 15130fdc8d8SChris Lattner { 15230fdc8d8SChris Lattner return g_option_table; 15330fdc8d8SChris Lattner } 15430fdc8d8SChris Lattner 15530fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 15630fdc8d8SChris Lattner 157e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 15830fdc8d8SChris Lattner 15930fdc8d8SChris Lattner // Instance variables to hold the values for command options. 16030fdc8d8SChris Lattner 161889037d7SGreg Clayton FileSpec log_file; 16230fdc8d8SChris Lattner uint32_t log_options; 16330fdc8d8SChris Lattner }; 16430fdc8d8SChris Lattner 16530fdc8d8SChris Lattner protected: 16613d21e9aSBruce Mitchener bool 1675a988416SJim Ingham DoExecute (Args& args, 16813d21e9aSBruce Mitchener CommandReturnObject &result) override 1695a988416SJim Ingham { 1705a988416SJim Ingham if (args.GetArgumentCount() < 2) 1715a988416SJim Ingham { 1725a988416SJim Ingham result.AppendErrorWithFormat("%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); 1735a988416SJim Ingham } 1745a988416SJim Ingham else 1755a988416SJim Ingham { 1765a988416SJim Ingham std::string channel(args.GetArgumentAtIndex(0)); 1775a988416SJim Ingham args.Shift (); // Shift off the channel 178889037d7SGreg Clayton char log_file[PATH_MAX]; 179889037d7SGreg Clayton if (m_options.log_file) 180889037d7SGreg Clayton m_options.log_file.GetPath(log_file, sizeof(log_file)); 181889037d7SGreg Clayton else 182889037d7SGreg Clayton log_file[0] = '\0'; 1835a988416SJim Ingham bool success = m_interpreter.GetDebugger().EnableLog (channel.c_str(), 1845a988416SJim Ingham args.GetConstArgumentVector(), 185889037d7SGreg Clayton log_file, 1865a988416SJim Ingham m_options.log_options, 1875a988416SJim Ingham result.GetErrorStream()); 1885a988416SJim Ingham if (success) 1895a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1905a988416SJim Ingham else 1915a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 1925a988416SJim Ingham } 1935a988416SJim Ingham return result.Succeeded(); 1945a988416SJim Ingham } 1955a988416SJim Ingham 19630fdc8d8SChris Lattner CommandOptions m_options; 19730fdc8d8SChris Lattner }; 19830fdc8d8SChris Lattner 199e0d378b3SGreg Clayton OptionDefinition 20030fdc8d8SChris Lattner CommandObjectLogEnable::CommandOptions::g_option_table[] = 20130fdc8d8SChris Lattner { 202*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Set the destination file to log to."}, 203*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, 204*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose logging." }, 205*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable debug logging." }, 206*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, 207*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, 208*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, 209*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." }, 210*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, 211*26cac3afSEugene Zelenko { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to the log file instead of overwriting." }, 212*26cac3afSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } 21330fdc8d8SChris Lattner }; 21430fdc8d8SChris Lattner 2155a988416SJim Ingham class CommandObjectLogDisable : public CommandObjectParsed 21630fdc8d8SChris Lattner { 21730fdc8d8SChris Lattner public: 21830fdc8d8SChris Lattner //------------------------------------------------------------------ 21930fdc8d8SChris Lattner // Constructors and Destructors 22030fdc8d8SChris Lattner //------------------------------------------------------------------ 221a7015092SGreg Clayton CommandObjectLogDisable(CommandInterpreter &interpreter) : 2225a988416SJim Ingham CommandObjectParsed(interpreter, 223a7015092SGreg Clayton "log disable", 2247149fab4SCaroline Tice "Disable one or more log channel categories.", 225*26cac3afSEugene Zelenko nullptr) 22630fdc8d8SChris Lattner { 2277149fab4SCaroline Tice CommandArgumentEntry arg1; 2287149fab4SCaroline Tice CommandArgumentEntry arg2; 229405fe67fSCaroline Tice CommandArgumentData channel_arg; 2307149fab4SCaroline Tice CommandArgumentData category_arg; 231405fe67fSCaroline Tice 232405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 233405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 2347149fab4SCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 235405fe67fSCaroline Tice 236405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 2377149fab4SCaroline Tice arg1.push_back (channel_arg); 2387149fab4SCaroline Tice 2397149fab4SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 2407149fab4SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 2417149fab4SCaroline Tice 2427149fab4SCaroline Tice arg2.push_back (category_arg); 243405fe67fSCaroline Tice 244405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 2457149fab4SCaroline Tice m_arguments.push_back (arg1); 2467149fab4SCaroline Tice m_arguments.push_back (arg2); 24730fdc8d8SChris Lattner } 24830fdc8d8SChris Lattner 249*26cac3afSEugene Zelenko ~CommandObjectLogDisable() override = default; 25030fdc8d8SChris Lattner 2515a988416SJim Ingham protected: 25213d21e9aSBruce Mitchener bool 2535a988416SJim Ingham DoExecute (Args& args, 25413d21e9aSBruce Mitchener CommandReturnObject &result) override 25530fdc8d8SChris Lattner { 25630fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 25730fdc8d8SChris Lattner if (argc == 0) 25830fdc8d8SChris Lattner { 259dff04404SJim Ingham result.AppendErrorWithFormat("%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); 26030fdc8d8SChris Lattner } 26130fdc8d8SChris Lattner else 26230fdc8d8SChris Lattner { 26330fdc8d8SChris Lattner Log::Callbacks log_callbacks; 26430fdc8d8SChris Lattner 26520ad3c40SCaroline Tice std::string channel(args.GetArgumentAtIndex(0)); 26620ad3c40SCaroline Tice args.Shift (); // Shift off the channel 26757abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel.c_str()), log_callbacks)) 26830fdc8d8SChris Lattner { 269228063cdSJim Ingham log_callbacks.disable (args.GetConstArgumentVector(), &result.GetErrorStream()); 27030fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 27130fdc8d8SChris Lattner } 27230fdc8d8SChris Lattner else if (channel == "all") 27330fdc8d8SChris Lattner { 27420ad3c40SCaroline Tice Log::DisableAllLogChannels(&result.GetErrorStream()); 27530fdc8d8SChris Lattner } 27630fdc8d8SChris Lattner else 27730fdc8d8SChris Lattner { 278ab65b34fSGreg Clayton LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str())); 27930fdc8d8SChris Lattner if (log_channel_sp) 28030fdc8d8SChris Lattner { 281228063cdSJim Ingham log_channel_sp->Disable(args.GetConstArgumentVector(), &result.GetErrorStream()); 28230fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 28330fdc8d8SChris Lattner } 28430fdc8d8SChris Lattner else 28530fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0)); 28630fdc8d8SChris Lattner } 28730fdc8d8SChris Lattner } 28830fdc8d8SChris Lattner return result.Succeeded(); 28930fdc8d8SChris Lattner } 29030fdc8d8SChris Lattner }; 29130fdc8d8SChris Lattner 2925a988416SJim Ingham class CommandObjectLogList : public CommandObjectParsed 29330fdc8d8SChris Lattner { 29430fdc8d8SChris Lattner public: 29530fdc8d8SChris Lattner //------------------------------------------------------------------ 29630fdc8d8SChris Lattner // Constructors and Destructors 29730fdc8d8SChris Lattner //------------------------------------------------------------------ 298a7015092SGreg Clayton CommandObjectLogList(CommandInterpreter &interpreter) : 2995a988416SJim Ingham CommandObjectParsed(interpreter, 300a7015092SGreg Clayton "log list", 301405fe67fSCaroline Tice "List the log categories for one or more log channels. If none specified, lists them all.", 302*26cac3afSEugene Zelenko nullptr) 30330fdc8d8SChris Lattner { 304405fe67fSCaroline Tice CommandArgumentEntry arg; 305405fe67fSCaroline Tice CommandArgumentData channel_arg; 306405fe67fSCaroline Tice 307405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 308405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 309405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatStar; 310405fe67fSCaroline Tice 311405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 312405fe67fSCaroline Tice arg.push_back (channel_arg); 313405fe67fSCaroline Tice 314405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 315405fe67fSCaroline Tice m_arguments.push_back (arg); 31630fdc8d8SChris Lattner } 31730fdc8d8SChris Lattner 318*26cac3afSEugene Zelenko ~CommandObjectLogList() override = default; 31930fdc8d8SChris Lattner 3205a988416SJim Ingham protected: 32113d21e9aSBruce Mitchener bool 3225a988416SJim Ingham DoExecute (Args& args, 32313d21e9aSBruce Mitchener CommandReturnObject &result) override 32430fdc8d8SChris Lattner { 32530fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 32630fdc8d8SChris Lattner if (argc == 0) 32730fdc8d8SChris Lattner { 32830fdc8d8SChris Lattner Log::ListAllLogChannels (&result.GetOutputStream()); 32930fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 33030fdc8d8SChris Lattner } 33130fdc8d8SChris Lattner else 33230fdc8d8SChris Lattner { 33330fdc8d8SChris Lattner for (size_t i=0; i<argc; ++i) 33430fdc8d8SChris Lattner { 33530fdc8d8SChris Lattner Log::Callbacks log_callbacks; 33630fdc8d8SChris Lattner 33730fdc8d8SChris Lattner std::string channel(args.GetArgumentAtIndex(i)); 33857abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel.c_str()), log_callbacks)) 33930fdc8d8SChris Lattner { 34030fdc8d8SChris Lattner log_callbacks.list_categories (&result.GetOutputStream()); 34130fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 34230fdc8d8SChris Lattner } 34330fdc8d8SChris Lattner else if (channel == "all") 34430fdc8d8SChris Lattner { 34530fdc8d8SChris Lattner Log::ListAllLogChannels (&result.GetOutputStream()); 34630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 34730fdc8d8SChris Lattner } 34830fdc8d8SChris Lattner else 34930fdc8d8SChris Lattner { 350ab65b34fSGreg Clayton LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str())); 35130fdc8d8SChris Lattner if (log_channel_sp) 35230fdc8d8SChris Lattner { 35330fdc8d8SChris Lattner log_channel_sp->ListCategories(&result.GetOutputStream()); 35430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 35530fdc8d8SChris Lattner } 35630fdc8d8SChris Lattner else 35730fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0)); 35830fdc8d8SChris Lattner } 35930fdc8d8SChris Lattner } 36030fdc8d8SChris Lattner } 36130fdc8d8SChris Lattner return result.Succeeded(); 36230fdc8d8SChris Lattner } 36330fdc8d8SChris Lattner }; 36430fdc8d8SChris Lattner 3655a988416SJim Ingham class CommandObjectLogTimer : public CommandObjectParsed 36630fdc8d8SChris Lattner { 36730fdc8d8SChris Lattner public: 36830fdc8d8SChris Lattner //------------------------------------------------------------------ 36930fdc8d8SChris Lattner // Constructors and Destructors 37030fdc8d8SChris Lattner //------------------------------------------------------------------ 371a7015092SGreg Clayton CommandObjectLogTimer(CommandInterpreter &interpreter) : 3725a988416SJim Ingham CommandObjectParsed (interpreter, 373a7015092SGreg Clayton "log timers", 37430fdc8d8SChris Lattner "Enable, disable, dump, and reset LLDB internal performance timers.", 375f7f4f501SJim Ingham "log timers < enable <depth> | disable | dump | increment <bool> | reset >") 37630fdc8d8SChris Lattner { 37730fdc8d8SChris Lattner } 37830fdc8d8SChris Lattner 379*26cac3afSEugene Zelenko ~CommandObjectLogTimer() override = default; 38030fdc8d8SChris Lattner 3815a988416SJim Ingham protected: 38213d21e9aSBruce Mitchener bool 3835a988416SJim Ingham DoExecute (Args& args, 38413d21e9aSBruce Mitchener CommandReturnObject &result) override 38530fdc8d8SChris Lattner { 38630fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 38730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 38830fdc8d8SChris Lattner 38930fdc8d8SChris Lattner if (argc == 1) 39030fdc8d8SChris Lattner { 39130fdc8d8SChris Lattner const char *sub_command = args.GetArgumentAtIndex(0); 39230fdc8d8SChris Lattner 39330fdc8d8SChris Lattner if (strcasecmp(sub_command, "enable") == 0) 39430fdc8d8SChris Lattner { 39530fdc8d8SChris Lattner Timer::SetDisplayDepth (UINT32_MAX); 39630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 39730fdc8d8SChris Lattner } 39830fdc8d8SChris Lattner else if (strcasecmp(sub_command, "disable") == 0) 39930fdc8d8SChris Lattner { 40030fdc8d8SChris Lattner Timer::DumpCategoryTimes (&result.GetOutputStream()); 40130fdc8d8SChris Lattner Timer::SetDisplayDepth (0); 40230fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 40330fdc8d8SChris Lattner } 40430fdc8d8SChris Lattner else if (strcasecmp(sub_command, "dump") == 0) 40530fdc8d8SChris Lattner { 40630fdc8d8SChris Lattner Timer::DumpCategoryTimes (&result.GetOutputStream()); 40730fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 40830fdc8d8SChris Lattner } 40930fdc8d8SChris Lattner else if (strcasecmp(sub_command, "reset") == 0) 41030fdc8d8SChris Lattner { 41130fdc8d8SChris Lattner Timer::ResetCategoryTimes (); 41230fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 41330fdc8d8SChris Lattner } 41430fdc8d8SChris Lattner } 415932725faSJim Ingham else if (argc == 2) 416932725faSJim Ingham { 417932725faSJim Ingham const char *sub_command = args.GetArgumentAtIndex(0); 418932725faSJim Ingham 419932725faSJim Ingham if (strcasecmp(sub_command, "enable") == 0) 420932725faSJim Ingham { 421932725faSJim Ingham bool success; 4225275aaa0SVince Harron uint32_t depth = StringConvert::ToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success); 423932725faSJim Ingham if (success) 424932725faSJim Ingham { 425932725faSJim Ingham Timer::SetDisplayDepth (depth); 426932725faSJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 427932725faSJim Ingham } 428932725faSJim Ingham else 429932725faSJim Ingham result.AppendError("Could not convert enable depth to an unsigned integer."); 430932725faSJim Ingham } 431f7f4f501SJim Ingham if (strcasecmp(sub_command, "increment") == 0) 432f7f4f501SJim Ingham { 433f7f4f501SJim Ingham bool success; 434f7f4f501SJim Ingham bool increment = Args::StringToBoolean(args.GetArgumentAtIndex(1), false, &success); 435f7f4f501SJim Ingham if (success) 436f7f4f501SJim Ingham { 437f7f4f501SJim Ingham Timer::SetQuiet (!increment); 438f7f4f501SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 439f7f4f501SJim Ingham } 440f7f4f501SJim Ingham else 441f7f4f501SJim Ingham result.AppendError("Could not convert increment value to boolean."); 442f7f4f501SJim Ingham } 443932725faSJim Ingham } 444932725faSJim Ingham 44530fdc8d8SChris Lattner if (!result.Succeeded()) 44630fdc8d8SChris Lattner { 44730fdc8d8SChris Lattner result.AppendError("Missing subcommand"); 44830fdc8d8SChris Lattner result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 44930fdc8d8SChris Lattner } 45030fdc8d8SChris Lattner return result.Succeeded(); 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner }; 45330fdc8d8SChris Lattner 4546611103cSGreg Clayton CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) : 455a7015092SGreg Clayton CommandObjectMultiword (interpreter, 456a7015092SGreg Clayton "log", 45730fdc8d8SChris Lattner "A set of commands for operating on logs.", 45830fdc8d8SChris Lattner "log <command> [<command-options>]") 45930fdc8d8SChris Lattner { 460a7015092SGreg Clayton LoadSubCommand ("enable", CommandObjectSP (new CommandObjectLogEnable (interpreter))); 461a7015092SGreg Clayton LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter))); 462a7015092SGreg Clayton LoadSubCommand ("list", CommandObjectSP (new CommandObjectLogList (interpreter))); 463a7015092SGreg Clayton LoadSubCommand ("timers", CommandObjectSP (new CommandObjectLogTimer (interpreter))); 46430fdc8d8SChris Lattner } 46530fdc8d8SChris Lattner 466*26cac3afSEugene Zelenko CommandObjectLog::~CommandObjectLog() = default; 467