180814287SRaphael Isemann //===-- CommandObjectLog.cpp ----------------------------------------------===// 230fdc8d8SChris Lattner // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 630fdc8d8SChris Lattner // 730fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 830fdc8d8SChris Lattner 926cac3afSEugene Zelenko #include "CommandObjectLog.h" 1030fdc8d8SChris Lattner #include "lldb/Core/Debugger.h" 113eb2b44dSZachary Turner #include "lldb/Host/OptionParser.h" 1230fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 1347cbf4a0SPavel Labath #include "lldb/Interpreter/OptionArgParser.h" 14*09dea546SJonas Devlieghere #include "lldb/Interpreter/OptionValueUInt64.h" 15b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h" 16145d95c9SPavel Labath #include "lldb/Utility/Args.h" 175713a05bSZachary Turner #include "lldb/Utility/FileSpec.h" 186f9e6901SZachary Turner #include "lldb/Utility/Log.h" 19bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 2038d0632eSPavel Labath #include "lldb/Utility/Timer.h" 2130fdc8d8SChris Lattner 2230fdc8d8SChris Lattner using namespace lldb; 2330fdc8d8SChris Lattner using namespace lldb_private; 2430fdc8d8SChris Lattner 25*09dea546SJonas Devlieghere #define LLDB_OPTIONS_log_enable 26ec67e734SRaphael Isemann #include "CommandOptions.inc" 271f0f5b5bSZachary Turner 286ba63d88SRaphael Isemann /// Common completion logic for log enable/disable. 296ba63d88SRaphael Isemann static void CompleteEnableDisable(CompletionRequest &request) { 306ba63d88SRaphael Isemann size_t arg_index = request.GetCursorIndex(); 316ba63d88SRaphael Isemann if (arg_index == 0) { // We got: log enable/disable x[tab] 326ba63d88SRaphael Isemann for (llvm::StringRef channel : Log::ListChannels()) 336ba63d88SRaphael Isemann request.TryCompleteCurrentArg(channel); 346ba63d88SRaphael Isemann } else if (arg_index >= 1) { // We got: log enable/disable channel x[tab] 356ba63d88SRaphael Isemann llvm::StringRef channel = request.GetParsedLine().GetArgumentAtIndex(0); 366ba63d88SRaphael Isemann Log::ForEachChannelCategory( 376ba63d88SRaphael Isemann channel, [&request](llvm::StringRef name, llvm::StringRef desc) { 386ba63d88SRaphael Isemann request.TryCompleteCurrentArg(name, desc); 396ba63d88SRaphael Isemann }); 406ba63d88SRaphael Isemann } 416ba63d88SRaphael Isemann } 426ba63d88SRaphael Isemann 43b9c1b51eSKate Stone class CommandObjectLogEnable : public CommandObjectParsed { 4430fdc8d8SChris Lattner public: 4530fdc8d8SChris Lattner // Constructors and Destructors 46b9c1b51eSKate Stone CommandObjectLogEnable(CommandInterpreter &interpreter) 47b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log enable", 4830fdc8d8SChris Lattner "Enable logging for a single log channel.", 49abb0ed44SKazu Hirata nullptr) { 50ceb6b139SCaroline Tice CommandArgumentEntry arg1; 51ceb6b139SCaroline Tice CommandArgumentEntry arg2; 52405fe67fSCaroline Tice CommandArgumentData channel_arg; 53ceb6b139SCaroline Tice CommandArgumentData category_arg; 54405fe67fSCaroline Tice 55405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 56405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 57405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 58405fe67fSCaroline Tice 59b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 60b9c1b51eSKate Stone // argument entry. 61ceb6b139SCaroline Tice arg1.push_back(channel_arg); 62ceb6b139SCaroline Tice 63ceb6b139SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 64ceb6b139SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 65ceb6b139SCaroline Tice 66ceb6b139SCaroline Tice arg2.push_back(category_arg); 67405fe67fSCaroline Tice 68405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 69ceb6b139SCaroline Tice m_arguments.push_back(arg1); 70ceb6b139SCaroline Tice m_arguments.push_back(arg2); 7130fdc8d8SChris Lattner } 7230fdc8d8SChris Lattner 7326cac3afSEugene Zelenko ~CommandObjectLogEnable() override = default; 7430fdc8d8SChris Lattner 75b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 7630fdc8d8SChris Lattner 77b9c1b51eSKate Stone class CommandOptions : public Options { 7830fdc8d8SChris Lattner public: 7924f9a2f5SShafik Yaghmour CommandOptions() = default; 8030fdc8d8SChris Lattner 8126cac3afSEugene Zelenko ~CommandOptions() override = default; 8230fdc8d8SChris Lattner 8397206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 84b9c1b51eSKate Stone ExecutionContext *execution_context) override { 8597206d57SZachary Turner Status error; 863bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 8730fdc8d8SChris Lattner 88b9c1b51eSKate Stone switch (short_option) { 89b9c1b51eSKate Stone case 'f': 908f3be7a3SJonas Devlieghere log_file.SetFile(option_arg, FileSpec::Style::native); 918f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(log_file); 92b9c1b51eSKate Stone break; 93*09dea546SJonas Devlieghere case 'b': 94*09dea546SJonas Devlieghere error = 95*09dea546SJonas Devlieghere buffer_size.SetValueFromString(option_arg, eVarSetOperationAssign); 96*09dea546SJonas Devlieghere break; 97b9c1b51eSKate Stone case 't': 98b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_THREADSAFE; 99b9c1b51eSKate Stone break; 100b9c1b51eSKate Stone case 'v': 101b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_VERBOSE; 102b9c1b51eSKate Stone break; 103b9c1b51eSKate Stone case 's': 104b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; 105b9c1b51eSKate Stone break; 106b9c1b51eSKate Stone case 'T': 107b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; 108b9c1b51eSKate Stone break; 109b9c1b51eSKate Stone case 'p': 110b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD; 111b9c1b51eSKate Stone break; 112b9c1b51eSKate Stone case 'n': 113b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 114b9c1b51eSKate Stone break; 115b9c1b51eSKate Stone case 'S': 116b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_BACKTRACE; 117b9c1b51eSKate Stone break; 118b9c1b51eSKate Stone case 'a': 119b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_APPEND; 120b9c1b51eSKate Stone break; 121107d9bbdSPavel Labath case 'F': 122107d9bbdSPavel Labath log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION; 12390505a0aSPavel Labath break; 12430fdc8d8SChris Lattner default: 12536162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 12630fdc8d8SChris Lattner } 12730fdc8d8SChris Lattner 12830fdc8d8SChris Lattner return error; 12930fdc8d8SChris Lattner } 13030fdc8d8SChris Lattner 131b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 132889037d7SGreg Clayton log_file.Clear(); 133*09dea546SJonas Devlieghere buffer_size.Clear(); 13430fdc8d8SChris Lattner log_options = 0; 13530fdc8d8SChris Lattner } 13630fdc8d8SChris Lattner 1371f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 138*09dea546SJonas Devlieghere return llvm::makeArrayRef(g_log_enable_options); 1391f0f5b5bSZachary Turner } 14030fdc8d8SChris Lattner 141889037d7SGreg Clayton FileSpec log_file; 142*09dea546SJonas Devlieghere OptionValueUInt64 buffer_size; 1439494c510SJonas Devlieghere uint32_t log_options = 0; 14430fdc8d8SChris Lattner }; 14530fdc8d8SChris Lattner 1466ba63d88SRaphael Isemann void 1476ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 1486ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 1496ba63d88SRaphael Isemann CompleteEnableDisable(request); 1506ba63d88SRaphael Isemann } 1516ba63d88SRaphael Isemann 15230fdc8d8SChris Lattner protected: 153b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 154b9c1b51eSKate Stone if (args.GetArgumentCount() < 2) { 155b9c1b51eSKate Stone result.AppendErrorWithFormat( 156b9c1b51eSKate Stone "%s takes a log channel and one or more log types.\n", 157b9c1b51eSKate Stone m_cmd_name.c_str()); 15811eb9c64SZachary Turner return false; 15911eb9c64SZachary Turner } 16011eb9c64SZachary Turner 16111eb9c64SZachary Turner // Store into a std::string since we're about to shift the channel off. 162adcd0268SBenjamin Kramer const std::string channel = std::string(args[0].ref()); 1635a988416SJim Ingham args.Shift(); // Shift off the channel 164889037d7SGreg Clayton char log_file[PATH_MAX]; 165889037d7SGreg Clayton if (m_options.log_file) 166889037d7SGreg Clayton m_options.log_file.GetPath(log_file, sizeof(log_file)); 167889037d7SGreg Clayton else 168889037d7SGreg Clayton log_file[0] = '\0'; 169775588c0SPavel Labath 170775588c0SPavel Labath std::string error; 171775588c0SPavel Labath llvm::raw_string_ostream error_stream(error); 172*09dea546SJonas Devlieghere bool success = GetDebugger().EnableLog( 173*09dea546SJonas Devlieghere channel, args.GetArgumentArrayRef(), log_file, m_options.log_options, 174*09dea546SJonas Devlieghere m_options.buffer_size.GetCurrentValue(), error_stream); 175775588c0SPavel Labath result.GetErrorStream() << error_stream.str(); 176775588c0SPavel Labath 1775a988416SJim Ingham if (success) 1785a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1795a988416SJim Ingham else 1805a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 1815a988416SJim Ingham return result.Succeeded(); 1825a988416SJim Ingham } 1835a988416SJim Ingham 18430fdc8d8SChris Lattner CommandOptions m_options; 18530fdc8d8SChris Lattner }; 18630fdc8d8SChris Lattner 187b9c1b51eSKate Stone class CommandObjectLogDisable : public CommandObjectParsed { 18830fdc8d8SChris Lattner public: 18930fdc8d8SChris Lattner // Constructors and Destructors 190b9c1b51eSKate Stone CommandObjectLogDisable(CommandInterpreter &interpreter) 191b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log disable", 1927149fab4SCaroline Tice "Disable one or more log channel categories.", 193b9c1b51eSKate Stone nullptr) { 1947149fab4SCaroline Tice CommandArgumentEntry arg1; 1957149fab4SCaroline Tice CommandArgumentEntry arg2; 196405fe67fSCaroline Tice CommandArgumentData channel_arg; 1977149fab4SCaroline Tice CommandArgumentData category_arg; 198405fe67fSCaroline Tice 199405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 200405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 2017149fab4SCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 202405fe67fSCaroline Tice 203b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 204b9c1b51eSKate Stone // argument entry. 2057149fab4SCaroline Tice arg1.push_back(channel_arg); 2067149fab4SCaroline Tice 2077149fab4SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 2087149fab4SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 2097149fab4SCaroline Tice 2107149fab4SCaroline Tice arg2.push_back(category_arg); 211405fe67fSCaroline Tice 212405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 2137149fab4SCaroline Tice m_arguments.push_back(arg1); 2147149fab4SCaroline Tice m_arguments.push_back(arg2); 21530fdc8d8SChris Lattner } 21630fdc8d8SChris Lattner 21726cac3afSEugene Zelenko ~CommandObjectLogDisable() override = default; 21830fdc8d8SChris Lattner 2196ba63d88SRaphael Isemann void 2206ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 2216ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 2226ba63d88SRaphael Isemann CompleteEnableDisable(request); 2236ba63d88SRaphael Isemann } 2246ba63d88SRaphael Isemann 2255a988416SJim Ingham protected: 226b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 22711eb9c64SZachary Turner if (args.empty()) { 228b9c1b51eSKate Stone result.AppendErrorWithFormat( 229b9c1b51eSKate Stone "%s takes a log channel and one or more log types.\n", 230b9c1b51eSKate Stone m_cmd_name.c_str()); 23111eb9c64SZachary Turner return false; 23211eb9c64SZachary Turner } 23311eb9c64SZachary Turner 234adcd0268SBenjamin Kramer const std::string channel = std::string(args[0].ref()); 23520ad3c40SCaroline Tice args.Shift(); // Shift off the channel 236fb0d22d6SPavel Labath if (channel == "all") { 237775588c0SPavel Labath Log::DisableAllLogChannels(); 2385fb8af40SPavel Labath result.SetStatus(eReturnStatusSuccessFinishNoResult); 239fb0d22d6SPavel Labath } else { 240775588c0SPavel Labath std::string error; 241775588c0SPavel Labath llvm::raw_string_ostream error_stream(error); 2425e336903SPavel Labath if (Log::DisableLogChannel(channel, args.GetArgumentArrayRef(), 243775588c0SPavel Labath error_stream)) 244fb0d22d6SPavel Labath result.SetStatus(eReturnStatusSuccessFinishNoResult); 245775588c0SPavel Labath result.GetErrorStream() << error_stream.str(); 24630fdc8d8SChris Lattner } 24730fdc8d8SChris Lattner return result.Succeeded(); 24830fdc8d8SChris Lattner } 24930fdc8d8SChris Lattner }; 25030fdc8d8SChris Lattner 251b9c1b51eSKate Stone class CommandObjectLogList : public CommandObjectParsed { 25230fdc8d8SChris Lattner public: 25330fdc8d8SChris Lattner // Constructors and Destructors 254b9c1b51eSKate Stone CommandObjectLogList(CommandInterpreter &interpreter) 255b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log list", 256b9c1b51eSKate Stone "List the log categories for one or more log " 257b9c1b51eSKate Stone "channels. If none specified, lists them all.", 258b9c1b51eSKate Stone nullptr) { 259405fe67fSCaroline Tice CommandArgumentEntry arg; 260405fe67fSCaroline Tice CommandArgumentData channel_arg; 261405fe67fSCaroline Tice 262405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 263405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 264405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatStar; 265405fe67fSCaroline Tice 266b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 267b9c1b51eSKate Stone // argument entry. 268405fe67fSCaroline Tice arg.push_back(channel_arg); 269405fe67fSCaroline Tice 270405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 271405fe67fSCaroline Tice m_arguments.push_back(arg); 27230fdc8d8SChris Lattner } 27330fdc8d8SChris Lattner 27426cac3afSEugene Zelenko ~CommandObjectLogList() override = default; 27530fdc8d8SChris Lattner 2766ba63d88SRaphael Isemann void 2776ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 2786ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 2796ba63d88SRaphael Isemann for (llvm::StringRef channel : Log::ListChannels()) 2806ba63d88SRaphael Isemann request.TryCompleteCurrentArg(channel); 2816ba63d88SRaphael Isemann } 2826ba63d88SRaphael Isemann 2835a988416SJim Ingham protected: 284b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 285775588c0SPavel Labath std::string output; 286775588c0SPavel Labath llvm::raw_string_ostream output_stream(output); 28711eb9c64SZachary Turner if (args.empty()) { 288775588c0SPavel Labath Log::ListAllLogChannels(output_stream); 28930fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 290b9c1b51eSKate Stone } else { 291fb0d22d6SPavel Labath bool success = true; 292fb0d22d6SPavel Labath for (const auto &entry : args.entries()) 293775588c0SPavel Labath success = 2940d9a201eSRaphael Isemann success && Log::ListChannelCategories(entry.ref(), output_stream); 295fb0d22d6SPavel Labath if (success) 29630fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 29730fdc8d8SChris Lattner } 298775588c0SPavel Labath result.GetOutputStream() << output_stream.str(); 29930fdc8d8SChris Lattner return result.Succeeded(); 30030fdc8d8SChris Lattner } 30130fdc8d8SChris Lattner }; 30230fdc8d8SChris Lattner 3031d3b7370SShu Anzai class CommandObjectLogTimerEnable : public CommandObjectParsed { 30430fdc8d8SChris Lattner public: 30530fdc8d8SChris Lattner // Constructors and Destructors 3061d3b7370SShu Anzai CommandObjectLogTimerEnable(CommandInterpreter &interpreter) 3071d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers enable", 3081d3b7370SShu Anzai "enable LLDB internal performance timers", 3091d3b7370SShu Anzai "log timers enable <depth>") { 3101d3b7370SShu Anzai CommandArgumentEntry arg; 3111d3b7370SShu Anzai CommandArgumentData depth_arg; 31230fdc8d8SChris Lattner 3131d3b7370SShu Anzai // Define the first (and only) variant of this arg. 3141d3b7370SShu Anzai depth_arg.arg_type = eArgTypeCount; 3151d3b7370SShu Anzai depth_arg.arg_repetition = eArgRepeatOptional; 3161d3b7370SShu Anzai 3171d3b7370SShu Anzai // There is only one variant this argument could be; put it into the 3181d3b7370SShu Anzai // argument entry. 3191d3b7370SShu Anzai arg.push_back(depth_arg); 3201d3b7370SShu Anzai 3211d3b7370SShu Anzai // Push the data for the first argument into the m_arguments vector. 3221d3b7370SShu Anzai m_arguments.push_back(arg); 3231d3b7370SShu Anzai } 3241d3b7370SShu Anzai 3251d3b7370SShu Anzai ~CommandObjectLogTimerEnable() override = default; 32630fdc8d8SChris Lattner 3275a988416SJim Ingham protected: 328b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 32930fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 33030fdc8d8SChris Lattner 3311d3b7370SShu Anzai if (args.GetArgumentCount() == 0) { 33230fdc8d8SChris Lattner Timer::SetDisplayDepth(UINT32_MAX); 33330fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 3341d3b7370SShu Anzai } else if (args.GetArgumentCount() == 1) { 33511eb9c64SZachary Turner uint32_t depth; 3361d3b7370SShu Anzai if (args[0].ref().consumeInteger(0, depth)) { 337b9c1b51eSKate Stone result.AppendError( 338b9c1b51eSKate Stone "Could not convert enable depth to an unsigned integer."); 33911eb9c64SZachary Turner } else { 34011eb9c64SZachary Turner Timer::SetDisplayDepth(depth); 34111eb9c64SZachary Turner result.SetStatus(eReturnStatusSuccessFinishNoResult); 342932725faSJim Ingham } 343932725faSJim Ingham } 344932725faSJim Ingham 345b9c1b51eSKate Stone if (!result.Succeeded()) { 34630fdc8d8SChris Lattner result.AppendError("Missing subcommand"); 34730fdc8d8SChris Lattner result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 34830fdc8d8SChris Lattner } 34930fdc8d8SChris Lattner return result.Succeeded(); 35030fdc8d8SChris Lattner } 35130fdc8d8SChris Lattner }; 35230fdc8d8SChris Lattner 3531d3b7370SShu Anzai class CommandObjectLogTimerDisable : public CommandObjectParsed { 3541d3b7370SShu Anzai public: 3551d3b7370SShu Anzai // Constructors and Destructors 3561d3b7370SShu Anzai CommandObjectLogTimerDisable(CommandInterpreter &interpreter) 3571d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers disable", 3581d3b7370SShu Anzai "disable LLDB internal performance timers", 3591d3b7370SShu Anzai nullptr) {} 3601d3b7370SShu Anzai 3611d3b7370SShu Anzai ~CommandObjectLogTimerDisable() override = default; 3621d3b7370SShu Anzai 3631d3b7370SShu Anzai protected: 3641d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 3651d3b7370SShu Anzai Timer::DumpCategoryTimes(&result.GetOutputStream()); 3661d3b7370SShu Anzai Timer::SetDisplayDepth(0); 3671d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 3681d3b7370SShu Anzai 3691d3b7370SShu Anzai if (!result.Succeeded()) { 3701d3b7370SShu Anzai result.AppendError("Missing subcommand"); 3711d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 3721d3b7370SShu Anzai } 3731d3b7370SShu Anzai return result.Succeeded(); 3741d3b7370SShu Anzai } 3751d3b7370SShu Anzai }; 3761d3b7370SShu Anzai 3771d3b7370SShu Anzai class CommandObjectLogTimerDump : public CommandObjectParsed { 3781d3b7370SShu Anzai public: 3791d3b7370SShu Anzai // Constructors and Destructors 3801d3b7370SShu Anzai CommandObjectLogTimerDump(CommandInterpreter &interpreter) 3811d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers dump", 3821d3b7370SShu Anzai "dump LLDB internal performance timers", nullptr) {} 3831d3b7370SShu Anzai 3841d3b7370SShu Anzai ~CommandObjectLogTimerDump() override = default; 3851d3b7370SShu Anzai 3861d3b7370SShu Anzai protected: 3871d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 3881d3b7370SShu Anzai Timer::DumpCategoryTimes(&result.GetOutputStream()); 3891d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 3901d3b7370SShu Anzai 3911d3b7370SShu Anzai if (!result.Succeeded()) { 3921d3b7370SShu Anzai result.AppendError("Missing subcommand"); 3931d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 3941d3b7370SShu Anzai } 3951d3b7370SShu Anzai return result.Succeeded(); 3961d3b7370SShu Anzai } 3971d3b7370SShu Anzai }; 3981d3b7370SShu Anzai 3991d3b7370SShu Anzai class CommandObjectLogTimerReset : public CommandObjectParsed { 4001d3b7370SShu Anzai public: 4011d3b7370SShu Anzai // Constructors and Destructors 4021d3b7370SShu Anzai CommandObjectLogTimerReset(CommandInterpreter &interpreter) 4031d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers reset", 4041d3b7370SShu Anzai "reset LLDB internal performance timers", nullptr) { 4051d3b7370SShu Anzai } 4061d3b7370SShu Anzai 4071d3b7370SShu Anzai ~CommandObjectLogTimerReset() override = default; 4081d3b7370SShu Anzai 4091d3b7370SShu Anzai protected: 4101d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 4111d3b7370SShu Anzai Timer::ResetCategoryTimes(); 4121d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 4131d3b7370SShu Anzai 4141d3b7370SShu Anzai if (!result.Succeeded()) { 4151d3b7370SShu Anzai result.AppendError("Missing subcommand"); 4161d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 4171d3b7370SShu Anzai } 4181d3b7370SShu Anzai return result.Succeeded(); 4191d3b7370SShu Anzai } 4201d3b7370SShu Anzai }; 4211d3b7370SShu Anzai 4221d3b7370SShu Anzai class CommandObjectLogTimerIncrement : public CommandObjectParsed { 4231d3b7370SShu Anzai public: 4241d3b7370SShu Anzai // Constructors and Destructors 4251d3b7370SShu Anzai CommandObjectLogTimerIncrement(CommandInterpreter &interpreter) 4261d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers increment", 4271d3b7370SShu Anzai "increment LLDB internal performance timers", 4281d3b7370SShu Anzai "log timers increment <bool>") { 4291d3b7370SShu Anzai CommandArgumentEntry arg; 4301d3b7370SShu Anzai CommandArgumentData bool_arg; 4311d3b7370SShu Anzai 4321d3b7370SShu Anzai // Define the first (and only) variant of this arg. 4331d3b7370SShu Anzai bool_arg.arg_type = eArgTypeBoolean; 4341d3b7370SShu Anzai bool_arg.arg_repetition = eArgRepeatPlain; 4351d3b7370SShu Anzai 4361d3b7370SShu Anzai // There is only one variant this argument could be; put it into the 4371d3b7370SShu Anzai // argument entry. 4381d3b7370SShu Anzai arg.push_back(bool_arg); 4391d3b7370SShu Anzai 4401d3b7370SShu Anzai // Push the data for the first argument into the m_arguments vector. 4411d3b7370SShu Anzai m_arguments.push_back(arg); 4421d3b7370SShu Anzai } 4431d3b7370SShu Anzai 4441d3b7370SShu Anzai ~CommandObjectLogTimerIncrement() override = default; 4451d3b7370SShu Anzai 4461d3b7370SShu Anzai void 4471d3b7370SShu Anzai HandleArgumentCompletion(CompletionRequest &request, 4481d3b7370SShu Anzai OptionElementVector &opt_element_vector) override { 4491d3b7370SShu Anzai request.TryCompleteCurrentArg("true"); 4501d3b7370SShu Anzai request.TryCompleteCurrentArg("false"); 4511d3b7370SShu Anzai } 4521d3b7370SShu Anzai 4531d3b7370SShu Anzai protected: 4541d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 4551d3b7370SShu Anzai result.SetStatus(eReturnStatusFailed); 4561d3b7370SShu Anzai 4571d3b7370SShu Anzai if (args.GetArgumentCount() == 1) { 4581d3b7370SShu Anzai bool success; 4591d3b7370SShu Anzai bool increment = 4601d3b7370SShu Anzai OptionArgParser::ToBoolean(args[0].ref(), false, &success); 4611d3b7370SShu Anzai 4621d3b7370SShu Anzai if (success) { 4631d3b7370SShu Anzai Timer::SetQuiet(!increment); 4641d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishNoResult); 4651d3b7370SShu Anzai } else 4661d3b7370SShu Anzai result.AppendError("Could not convert increment value to boolean."); 4671d3b7370SShu Anzai } 4681d3b7370SShu Anzai 4691d3b7370SShu Anzai if (!result.Succeeded()) { 4701d3b7370SShu Anzai result.AppendError("Missing subcommand"); 4711d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 4721d3b7370SShu Anzai } 4731d3b7370SShu Anzai return result.Succeeded(); 4741d3b7370SShu Anzai } 4751d3b7370SShu Anzai }; 4761d3b7370SShu Anzai 4771d3b7370SShu Anzai class CommandObjectLogTimer : public CommandObjectMultiword { 4781d3b7370SShu Anzai public: 4791d3b7370SShu Anzai CommandObjectLogTimer(CommandInterpreter &interpreter) 4801d3b7370SShu Anzai : CommandObjectMultiword(interpreter, "log timers", 4811d3b7370SShu Anzai "Enable, disable, dump, and reset LLDB internal " 4821d3b7370SShu Anzai "performance timers.", 4831d3b7370SShu Anzai "log timers < enable <depth> | disable | dump | " 4841d3b7370SShu Anzai "increment <bool> | reset >") { 4851d3b7370SShu Anzai LoadSubCommand("enable", CommandObjectSP( 4861d3b7370SShu Anzai new CommandObjectLogTimerEnable(interpreter))); 4871d3b7370SShu Anzai LoadSubCommand("disable", CommandObjectSP(new CommandObjectLogTimerDisable( 4881d3b7370SShu Anzai interpreter))); 4891d3b7370SShu Anzai LoadSubCommand("dump", 4901d3b7370SShu Anzai CommandObjectSP(new CommandObjectLogTimerDump(interpreter))); 4911d3b7370SShu Anzai LoadSubCommand( 4921d3b7370SShu Anzai "reset", CommandObjectSP(new CommandObjectLogTimerReset(interpreter))); 4931d3b7370SShu Anzai LoadSubCommand( 4941d3b7370SShu Anzai "increment", 4951d3b7370SShu Anzai CommandObjectSP(new CommandObjectLogTimerIncrement(interpreter))); 4961d3b7370SShu Anzai } 4971d3b7370SShu Anzai 4981d3b7370SShu Anzai ~CommandObjectLogTimer() override = default; 4991d3b7370SShu Anzai }; 5001d3b7370SShu Anzai 5017428a18cSKate Stone CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) 502b9c1b51eSKate Stone : CommandObjectMultiword(interpreter, "log", 503b9c1b51eSKate Stone "Commands controlling LLDB internal logging.", 504b9c1b51eSKate Stone "log <subcommand> [<command-options>]") { 505b9c1b51eSKate Stone LoadSubCommand("enable", 506b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogEnable(interpreter))); 507b9c1b51eSKate Stone LoadSubCommand("disable", 508b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogDisable(interpreter))); 509b9c1b51eSKate Stone LoadSubCommand("list", 510b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogList(interpreter))); 511b9c1b51eSKate Stone LoadSubCommand("timers", 512b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogTimer(interpreter))); 51330fdc8d8SChris Lattner } 51430fdc8d8SChris Lattner 51526cac3afSEugene Zelenko CommandObjectLog::~CommandObjectLog() = default; 516