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 1426cac3afSEugene 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.", 4926cac3afSEugene Zelenko nullptr), 50e1cfbc79STodd Fiala m_options() 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 7426cac3afSEugene 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: 107e1cfbc79STodd Fiala CommandOptions() : 108e1cfbc79STodd Fiala Options(), 10930fdc8d8SChris Lattner log_file(), 11030fdc8d8SChris Lattner log_options(0) 11130fdc8d8SChris Lattner { 11230fdc8d8SChris Lattner } 11330fdc8d8SChris Lattner 11426cac3afSEugene Zelenko ~CommandOptions () override = default; 11530fdc8d8SChris Lattner 11613d21e9aSBruce Mitchener Error 117e1cfbc79STodd Fiala SetOptionValue (uint32_t option_idx, const char *option_arg, 118e1cfbc79STodd Fiala ExecutionContext *execution_context) override 11930fdc8d8SChris Lattner { 12030fdc8d8SChris Lattner Error error; 1213bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 12230fdc8d8SChris Lattner 12330fdc8d8SChris Lattner switch (short_option) 12430fdc8d8SChris Lattner { 125889037d7SGreg Clayton case 'f': log_file.SetFile(option_arg, true); break; 12630fdc8d8SChris Lattner case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; break; 12730fdc8d8SChris Lattner case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break; 12830fdc8d8SChris Lattner case 'g': log_options |= LLDB_LOG_OPTION_DEBUG; break; 12930fdc8d8SChris Lattner case 's': log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; break; 13030fdc8d8SChris Lattner case 'T': log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; break; 13130fdc8d8SChris Lattner case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break; 13230fdc8d8SChris Lattner case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break; 1333a18e319SGreg Clayton case 'S': log_options |= LLDB_LOG_OPTION_BACKTRACE; break; 1348ac06996SPavel Labath case 'a': log_options |= LLDB_LOG_OPTION_APPEND; break; 13530fdc8d8SChris Lattner default: 13686edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 13730fdc8d8SChris Lattner break; 13830fdc8d8SChris Lattner } 13930fdc8d8SChris Lattner 14030fdc8d8SChris Lattner return error; 14130fdc8d8SChris Lattner } 14230fdc8d8SChris Lattner 14330fdc8d8SChris Lattner void 144e1cfbc79STodd Fiala OptionParsingStarting(ExecutionContext *execution_context) override 14530fdc8d8SChris Lattner { 146889037d7SGreg Clayton log_file.Clear(); 14730fdc8d8SChris Lattner log_options = 0; 14830fdc8d8SChris Lattner } 14930fdc8d8SChris Lattner 150e0d378b3SGreg Clayton const OptionDefinition* 15113d21e9aSBruce Mitchener GetDefinitions () override 15230fdc8d8SChris Lattner { 15330fdc8d8SChris Lattner return g_option_table; 15430fdc8d8SChris Lattner } 15530fdc8d8SChris Lattner 15630fdc8d8SChris Lattner // Options table: Required for subclasses of Options. 15730fdc8d8SChris Lattner 158e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 15930fdc8d8SChris Lattner 16030fdc8d8SChris Lattner // Instance variables to hold the values for command options. 16130fdc8d8SChris Lattner 162889037d7SGreg Clayton FileSpec log_file; 16330fdc8d8SChris Lattner uint32_t log_options; 16430fdc8d8SChris Lattner }; 16530fdc8d8SChris Lattner 16630fdc8d8SChris Lattner protected: 16713d21e9aSBruce Mitchener bool 1685a988416SJim Ingham DoExecute (Args& args, 16913d21e9aSBruce Mitchener CommandReturnObject &result) override 1705a988416SJim Ingham { 1715a988416SJim Ingham if (args.GetArgumentCount() < 2) 1725a988416SJim Ingham { 1735a988416SJim Ingham result.AppendErrorWithFormat("%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); 1745a988416SJim Ingham } 1755a988416SJim Ingham else 1765a988416SJim Ingham { 1775a988416SJim Ingham std::string channel(args.GetArgumentAtIndex(0)); 1785a988416SJim Ingham args.Shift (); // Shift off the channel 179889037d7SGreg Clayton char log_file[PATH_MAX]; 180889037d7SGreg Clayton if (m_options.log_file) 181889037d7SGreg Clayton m_options.log_file.GetPath(log_file, sizeof(log_file)); 182889037d7SGreg Clayton else 183889037d7SGreg Clayton log_file[0] = '\0'; 1845a988416SJim Ingham bool success = m_interpreter.GetDebugger().EnableLog (channel.c_str(), 1855a988416SJim Ingham args.GetConstArgumentVector(), 186889037d7SGreg Clayton log_file, 1875a988416SJim Ingham m_options.log_options, 1885a988416SJim Ingham result.GetErrorStream()); 1895a988416SJim Ingham if (success) 1905a988416SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 1915a988416SJim Ingham else 1925a988416SJim Ingham result.SetStatus (eReturnStatusFailed); 1935a988416SJim Ingham } 1945a988416SJim Ingham return result.Succeeded(); 1955a988416SJim Ingham } 1965a988416SJim Ingham 19730fdc8d8SChris Lattner CommandOptions m_options; 19830fdc8d8SChris Lattner }; 19930fdc8d8SChris Lattner 200e0d378b3SGreg Clayton OptionDefinition 20130fdc8d8SChris Lattner CommandObjectLogEnable::CommandOptions::g_option_table[] = 20230fdc8d8SChris Lattner { 203*ac9c3a62SKate Stone // clang-format off 20426cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Set the destination file to log to."}, 20526cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines."}, 20626cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose logging."}, 20726cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable debug logging."}, 20826cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id."}, 20926cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with a timestamp."}, 21026cac3afSEugene 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."}, 21126cac3afSEugene 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."}, 21226cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append a stack backtrace to each log line."}, 21326cac3afSEugene Zelenko {LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to the log file instead of overwriting."}, 21426cac3afSEugene Zelenko {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr} 215*ac9c3a62SKate Stone // clang-format on 21630fdc8d8SChris Lattner }; 21730fdc8d8SChris Lattner 2185a988416SJim Ingham class CommandObjectLogDisable : public CommandObjectParsed 21930fdc8d8SChris Lattner { 22030fdc8d8SChris Lattner public: 22130fdc8d8SChris Lattner //------------------------------------------------------------------ 22230fdc8d8SChris Lattner // Constructors and Destructors 22330fdc8d8SChris Lattner //------------------------------------------------------------------ 224a7015092SGreg Clayton CommandObjectLogDisable(CommandInterpreter &interpreter) : 2255a988416SJim Ingham CommandObjectParsed(interpreter, 226a7015092SGreg Clayton "log disable", 2277149fab4SCaroline Tice "Disable one or more log channel categories.", 22826cac3afSEugene Zelenko nullptr) 22930fdc8d8SChris Lattner { 2307149fab4SCaroline Tice CommandArgumentEntry arg1; 2317149fab4SCaroline Tice CommandArgumentEntry arg2; 232405fe67fSCaroline Tice CommandArgumentData channel_arg; 2337149fab4SCaroline Tice CommandArgumentData category_arg; 234405fe67fSCaroline Tice 235405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 236405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 2377149fab4SCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 238405fe67fSCaroline Tice 239405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 2407149fab4SCaroline Tice arg1.push_back (channel_arg); 2417149fab4SCaroline Tice 2427149fab4SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 2437149fab4SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 2447149fab4SCaroline Tice 2457149fab4SCaroline Tice arg2.push_back (category_arg); 246405fe67fSCaroline Tice 247405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 2487149fab4SCaroline Tice m_arguments.push_back (arg1); 2497149fab4SCaroline Tice m_arguments.push_back (arg2); 25030fdc8d8SChris Lattner } 25130fdc8d8SChris Lattner 25226cac3afSEugene Zelenko ~CommandObjectLogDisable() override = default; 25330fdc8d8SChris Lattner 2545a988416SJim Ingham protected: 25513d21e9aSBruce Mitchener bool 2565a988416SJim Ingham DoExecute (Args& args, 25713d21e9aSBruce Mitchener CommandReturnObject &result) override 25830fdc8d8SChris Lattner { 25930fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 26030fdc8d8SChris Lattner if (argc == 0) 26130fdc8d8SChris Lattner { 262dff04404SJim Ingham result.AppendErrorWithFormat("%s takes a log channel and one or more log types.\n", m_cmd_name.c_str()); 26330fdc8d8SChris Lattner } 26430fdc8d8SChris Lattner else 26530fdc8d8SChris Lattner { 26630fdc8d8SChris Lattner Log::Callbacks log_callbacks; 26730fdc8d8SChris Lattner 26820ad3c40SCaroline Tice std::string channel(args.GetArgumentAtIndex(0)); 26920ad3c40SCaroline Tice args.Shift (); // Shift off the channel 27057abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel.c_str()), log_callbacks)) 27130fdc8d8SChris Lattner { 272228063cdSJim Ingham log_callbacks.disable (args.GetConstArgumentVector(), &result.GetErrorStream()); 27330fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 27430fdc8d8SChris Lattner } 27530fdc8d8SChris Lattner else if (channel == "all") 27630fdc8d8SChris Lattner { 27720ad3c40SCaroline Tice Log::DisableAllLogChannels(&result.GetErrorStream()); 27830fdc8d8SChris Lattner } 27930fdc8d8SChris Lattner else 28030fdc8d8SChris Lattner { 281ab65b34fSGreg Clayton LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str())); 28230fdc8d8SChris Lattner if (log_channel_sp) 28330fdc8d8SChris Lattner { 284228063cdSJim Ingham log_channel_sp->Disable(args.GetConstArgumentVector(), &result.GetErrorStream()); 28530fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 28630fdc8d8SChris Lattner } 28730fdc8d8SChris Lattner else 28830fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0)); 28930fdc8d8SChris Lattner } 29030fdc8d8SChris Lattner } 29130fdc8d8SChris Lattner return result.Succeeded(); 29230fdc8d8SChris Lattner } 29330fdc8d8SChris Lattner }; 29430fdc8d8SChris Lattner 2955a988416SJim Ingham class CommandObjectLogList : public CommandObjectParsed 29630fdc8d8SChris Lattner { 29730fdc8d8SChris Lattner public: 29830fdc8d8SChris Lattner //------------------------------------------------------------------ 29930fdc8d8SChris Lattner // Constructors and Destructors 30030fdc8d8SChris Lattner //------------------------------------------------------------------ 301a7015092SGreg Clayton CommandObjectLogList(CommandInterpreter &interpreter) : 3025a988416SJim Ingham CommandObjectParsed(interpreter, 303a7015092SGreg Clayton "log list", 304405fe67fSCaroline Tice "List the log categories for one or more log channels. If none specified, lists them all.", 30526cac3afSEugene Zelenko nullptr) 30630fdc8d8SChris Lattner { 307405fe67fSCaroline Tice CommandArgumentEntry arg; 308405fe67fSCaroline Tice CommandArgumentData channel_arg; 309405fe67fSCaroline Tice 310405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 311405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 312405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatStar; 313405fe67fSCaroline Tice 314405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 315405fe67fSCaroline Tice arg.push_back (channel_arg); 316405fe67fSCaroline Tice 317405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 318405fe67fSCaroline Tice m_arguments.push_back (arg); 31930fdc8d8SChris Lattner } 32030fdc8d8SChris Lattner 32126cac3afSEugene Zelenko ~CommandObjectLogList() override = default; 32230fdc8d8SChris Lattner 3235a988416SJim Ingham protected: 32413d21e9aSBruce Mitchener bool 3255a988416SJim Ingham DoExecute (Args& args, 32613d21e9aSBruce Mitchener CommandReturnObject &result) override 32730fdc8d8SChris Lattner { 32830fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 32930fdc8d8SChris Lattner if (argc == 0) 33030fdc8d8SChris Lattner { 33130fdc8d8SChris Lattner Log::ListAllLogChannels (&result.GetOutputStream()); 33230fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 33330fdc8d8SChris Lattner } 33430fdc8d8SChris Lattner else 33530fdc8d8SChris Lattner { 33630fdc8d8SChris Lattner for (size_t i=0; i<argc; ++i) 33730fdc8d8SChris Lattner { 33830fdc8d8SChris Lattner Log::Callbacks log_callbacks; 33930fdc8d8SChris Lattner 34030fdc8d8SChris Lattner std::string channel(args.GetArgumentAtIndex(i)); 34157abc5d6SGreg Clayton if (Log::GetLogChannelCallbacks (ConstString(channel.c_str()), log_callbacks)) 34230fdc8d8SChris Lattner { 34330fdc8d8SChris Lattner log_callbacks.list_categories (&result.GetOutputStream()); 34430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 34530fdc8d8SChris Lattner } 34630fdc8d8SChris Lattner else if (channel == "all") 34730fdc8d8SChris Lattner { 34830fdc8d8SChris Lattner Log::ListAllLogChannels (&result.GetOutputStream()); 34930fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 35030fdc8d8SChris Lattner } 35130fdc8d8SChris Lattner else 35230fdc8d8SChris Lattner { 353ab65b34fSGreg Clayton LogChannelSP log_channel_sp (LogChannel::FindPlugin(channel.c_str())); 35430fdc8d8SChris Lattner if (log_channel_sp) 35530fdc8d8SChris Lattner { 35630fdc8d8SChris Lattner log_channel_sp->ListCategories(&result.GetOutputStream()); 35730fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 35830fdc8d8SChris Lattner } 35930fdc8d8SChris Lattner else 36030fdc8d8SChris Lattner result.AppendErrorWithFormat("Invalid log channel '%s'.\n", args.GetArgumentAtIndex(0)); 36130fdc8d8SChris Lattner } 36230fdc8d8SChris Lattner } 36330fdc8d8SChris Lattner } 36430fdc8d8SChris Lattner return result.Succeeded(); 36530fdc8d8SChris Lattner } 36630fdc8d8SChris Lattner }; 36730fdc8d8SChris Lattner 3685a988416SJim Ingham class CommandObjectLogTimer : public CommandObjectParsed 36930fdc8d8SChris Lattner { 37030fdc8d8SChris Lattner public: 37130fdc8d8SChris Lattner //------------------------------------------------------------------ 37230fdc8d8SChris Lattner // Constructors and Destructors 37330fdc8d8SChris Lattner //------------------------------------------------------------------ 374a7015092SGreg Clayton CommandObjectLogTimer(CommandInterpreter &interpreter) : 3755a988416SJim Ingham CommandObjectParsed (interpreter, 376a7015092SGreg Clayton "log timers", 37730fdc8d8SChris Lattner "Enable, disable, dump, and reset LLDB internal performance timers.", 378f7f4f501SJim Ingham "log timers < enable <depth> | disable | dump | increment <bool> | reset >") 37930fdc8d8SChris Lattner { 38030fdc8d8SChris Lattner } 38130fdc8d8SChris Lattner 38226cac3afSEugene Zelenko ~CommandObjectLogTimer() override = default; 38330fdc8d8SChris Lattner 3845a988416SJim Ingham protected: 38513d21e9aSBruce Mitchener bool 3865a988416SJim Ingham DoExecute (Args& args, 38713d21e9aSBruce Mitchener CommandReturnObject &result) override 38830fdc8d8SChris Lattner { 38930fdc8d8SChris Lattner const size_t argc = args.GetArgumentCount(); 39030fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 39130fdc8d8SChris Lattner 39230fdc8d8SChris Lattner if (argc == 1) 39330fdc8d8SChris Lattner { 39430fdc8d8SChris Lattner const char *sub_command = args.GetArgumentAtIndex(0); 39530fdc8d8SChris Lattner 39630fdc8d8SChris Lattner if (strcasecmp(sub_command, "enable") == 0) 39730fdc8d8SChris Lattner { 39830fdc8d8SChris Lattner Timer::SetDisplayDepth (UINT32_MAX); 39930fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 40030fdc8d8SChris Lattner } 40130fdc8d8SChris Lattner else if (strcasecmp(sub_command, "disable") == 0) 40230fdc8d8SChris Lattner { 40330fdc8d8SChris Lattner Timer::DumpCategoryTimes (&result.GetOutputStream()); 40430fdc8d8SChris Lattner Timer::SetDisplayDepth (0); 40530fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 40630fdc8d8SChris Lattner } 40730fdc8d8SChris Lattner else if (strcasecmp(sub_command, "dump") == 0) 40830fdc8d8SChris Lattner { 40930fdc8d8SChris Lattner Timer::DumpCategoryTimes (&result.GetOutputStream()); 41030fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner else if (strcasecmp(sub_command, "reset") == 0) 41330fdc8d8SChris Lattner { 41430fdc8d8SChris Lattner Timer::ResetCategoryTimes (); 41530fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 41630fdc8d8SChris Lattner } 41730fdc8d8SChris Lattner } 418932725faSJim Ingham else if (argc == 2) 419932725faSJim Ingham { 420932725faSJim Ingham const char *sub_command = args.GetArgumentAtIndex(0); 421932725faSJim Ingham 422932725faSJim Ingham if (strcasecmp(sub_command, "enable") == 0) 423932725faSJim Ingham { 424932725faSJim Ingham bool success; 4255275aaa0SVince Harron uint32_t depth = StringConvert::ToUInt32(args.GetArgumentAtIndex(1), 0, 0, &success); 426932725faSJim Ingham if (success) 427932725faSJim Ingham { 428932725faSJim Ingham Timer::SetDisplayDepth (depth); 429932725faSJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 430932725faSJim Ingham } 431932725faSJim Ingham else 432932725faSJim Ingham result.AppendError("Could not convert enable depth to an unsigned integer."); 433932725faSJim Ingham } 434f7f4f501SJim Ingham if (strcasecmp(sub_command, "increment") == 0) 435f7f4f501SJim Ingham { 436f7f4f501SJim Ingham bool success; 437f7f4f501SJim Ingham bool increment = Args::StringToBoolean(args.GetArgumentAtIndex(1), false, &success); 438f7f4f501SJim Ingham if (success) 439f7f4f501SJim Ingham { 440f7f4f501SJim Ingham Timer::SetQuiet (!increment); 441f7f4f501SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 442f7f4f501SJim Ingham } 443f7f4f501SJim Ingham else 444f7f4f501SJim Ingham result.AppendError("Could not convert increment value to boolean."); 445f7f4f501SJim Ingham } 446932725faSJim Ingham } 447932725faSJim Ingham 44830fdc8d8SChris Lattner if (!result.Succeeded()) 44930fdc8d8SChris Lattner { 45030fdc8d8SChris Lattner result.AppendError("Missing subcommand"); 45130fdc8d8SChris Lattner result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 45230fdc8d8SChris Lattner } 45330fdc8d8SChris Lattner return result.Succeeded(); 45430fdc8d8SChris Lattner } 45530fdc8d8SChris Lattner }; 45630fdc8d8SChris Lattner 4577428a18cSKate Stone CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) 4587428a18cSKate Stone : CommandObjectMultiword(interpreter, "log", "Commands controlling LLDB internal logging.", 4597428a18cSKate Stone "log <subcommand> [<command-options>]") 46030fdc8d8SChris Lattner { 461a7015092SGreg Clayton LoadSubCommand ("enable", CommandObjectSP (new CommandObjectLogEnable (interpreter))); 462a7015092SGreg Clayton LoadSubCommand ("disable", CommandObjectSP (new CommandObjectLogDisable (interpreter))); 463a7015092SGreg Clayton LoadSubCommand ("list", CommandObjectSP (new CommandObjectLogList (interpreter))); 464a7015092SGreg Clayton LoadSubCommand ("timers", CommandObjectSP (new CommandObjectLogTimer (interpreter))); 46530fdc8d8SChris Lattner } 46630fdc8d8SChris Lattner 46726cac3afSEugene Zelenko CommandObjectLog::~CommandObjectLog() = default; 468