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" 14b9c1b51eSKate Stone #include "lldb/Interpreter/Options.h" 15145d95c9SPavel Labath #include "lldb/Utility/Args.h" 165713a05bSZachary Turner #include "lldb/Utility/FileSpec.h" 176f9e6901SZachary Turner #include "lldb/Utility/Log.h" 18bf9a7730SZachary Turner #include "lldb/Utility/Stream.h" 1938d0632eSPavel Labath #include "lldb/Utility/Timer.h" 2030fdc8d8SChris Lattner 2130fdc8d8SChris Lattner using namespace lldb; 2230fdc8d8SChris Lattner using namespace lldb_private; 2330fdc8d8SChris Lattner 24ec67e734SRaphael Isemann #define LLDB_OPTIONS_log 25ec67e734SRaphael Isemann #include "CommandOptions.inc" 261f0f5b5bSZachary Turner 276ba63d88SRaphael Isemann /// Common completion logic for log enable/disable. 286ba63d88SRaphael Isemann static void CompleteEnableDisable(CompletionRequest &request) { 296ba63d88SRaphael Isemann size_t arg_index = request.GetCursorIndex(); 306ba63d88SRaphael Isemann if (arg_index == 0) { // We got: log enable/disable x[tab] 316ba63d88SRaphael Isemann for (llvm::StringRef channel : Log::ListChannels()) 326ba63d88SRaphael Isemann request.TryCompleteCurrentArg(channel); 336ba63d88SRaphael Isemann } else if (arg_index >= 1) { // We got: log enable/disable channel x[tab] 346ba63d88SRaphael Isemann llvm::StringRef channel = request.GetParsedLine().GetArgumentAtIndex(0); 356ba63d88SRaphael Isemann Log::ForEachChannelCategory( 366ba63d88SRaphael Isemann channel, [&request](llvm::StringRef name, llvm::StringRef desc) { 376ba63d88SRaphael Isemann request.TryCompleteCurrentArg(name, desc); 386ba63d88SRaphael Isemann }); 396ba63d88SRaphael Isemann } 406ba63d88SRaphael Isemann } 416ba63d88SRaphael Isemann 42b9c1b51eSKate Stone class CommandObjectLogEnable : public CommandObjectParsed { 4330fdc8d8SChris Lattner public: 4430fdc8d8SChris Lattner // Constructors and Destructors 45b9c1b51eSKate Stone CommandObjectLogEnable(CommandInterpreter &interpreter) 46b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log enable", 4730fdc8d8SChris Lattner "Enable logging for a single log channel.", 4826cac3afSEugene Zelenko nullptr), 49b9c1b51eSKate Stone m_options() { 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: 79*9494c510SJonas Devlieghere CommandOptions() : Options(), log_file() {} 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; 93b9c1b51eSKate Stone case 't': 94b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_THREADSAFE; 95b9c1b51eSKate Stone break; 96b9c1b51eSKate Stone case 'v': 97b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_VERBOSE; 98b9c1b51eSKate Stone break; 99b9c1b51eSKate Stone case 's': 100b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; 101b9c1b51eSKate Stone break; 102b9c1b51eSKate Stone case 'T': 103b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; 104b9c1b51eSKate Stone break; 105b9c1b51eSKate Stone case 'p': 106b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD; 107b9c1b51eSKate Stone break; 108b9c1b51eSKate Stone case 'n': 109b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 110b9c1b51eSKate Stone break; 111b9c1b51eSKate Stone case 'S': 112b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_BACKTRACE; 113b9c1b51eSKate Stone break; 114b9c1b51eSKate Stone case 'a': 115b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_APPEND; 116b9c1b51eSKate Stone break; 117107d9bbdSPavel Labath case 'F': 118107d9bbdSPavel Labath log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION; 11990505a0aSPavel Labath break; 12030fdc8d8SChris Lattner default: 12136162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 12230fdc8d8SChris Lattner } 12330fdc8d8SChris Lattner 12430fdc8d8SChris Lattner return error; 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner 127b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 128889037d7SGreg Clayton log_file.Clear(); 12930fdc8d8SChris Lattner log_options = 0; 13030fdc8d8SChris Lattner } 13130fdc8d8SChris Lattner 1321f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 13370602439SZachary Turner return llvm::makeArrayRef(g_log_options); 1341f0f5b5bSZachary Turner } 13530fdc8d8SChris Lattner 13630fdc8d8SChris Lattner // Instance variables to hold the values for command options. 13730fdc8d8SChris Lattner 138889037d7SGreg Clayton FileSpec log_file; 139*9494c510SJonas Devlieghere uint32_t log_options = 0; 14030fdc8d8SChris Lattner }; 14130fdc8d8SChris Lattner 1426ba63d88SRaphael Isemann void 1436ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 1446ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 1456ba63d88SRaphael Isemann CompleteEnableDisable(request); 1466ba63d88SRaphael Isemann } 1476ba63d88SRaphael Isemann 14830fdc8d8SChris Lattner protected: 149b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 150b9c1b51eSKate Stone if (args.GetArgumentCount() < 2) { 151b9c1b51eSKate Stone result.AppendErrorWithFormat( 152b9c1b51eSKate Stone "%s takes a log channel and one or more log types.\n", 153b9c1b51eSKate Stone m_cmd_name.c_str()); 154434b81d0SRaphael Isemann result.SetStatus(eReturnStatusFailed); 15511eb9c64SZachary Turner return false; 15611eb9c64SZachary Turner } 15711eb9c64SZachary Turner 15811eb9c64SZachary Turner // Store into a std::string since we're about to shift the channel off. 159adcd0268SBenjamin Kramer const std::string channel = std::string(args[0].ref()); 1605a988416SJim Ingham args.Shift(); // Shift off the channel 161889037d7SGreg Clayton char log_file[PATH_MAX]; 162889037d7SGreg Clayton if (m_options.log_file) 163889037d7SGreg Clayton m_options.log_file.GetPath(log_file, sizeof(log_file)); 164889037d7SGreg Clayton else 165889037d7SGreg Clayton log_file[0] = '\0'; 166775588c0SPavel Labath 167775588c0SPavel Labath std::string error; 168775588c0SPavel Labath llvm::raw_string_ostream error_stream(error); 16957179860SJonas Devlieghere bool success = 17057179860SJonas Devlieghere GetDebugger().EnableLog(channel, args.GetArgumentArrayRef(), log_file, 17157179860SJonas Devlieghere m_options.log_options, error_stream); 172775588c0SPavel Labath result.GetErrorStream() << error_stream.str(); 173775588c0SPavel Labath 1745a988416SJim Ingham if (success) 1755a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1765a988416SJim Ingham else 1775a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 1785a988416SJim Ingham return result.Succeeded(); 1795a988416SJim Ingham } 1805a988416SJim Ingham 18130fdc8d8SChris Lattner CommandOptions m_options; 18230fdc8d8SChris Lattner }; 18330fdc8d8SChris Lattner 184b9c1b51eSKate Stone class CommandObjectLogDisable : public CommandObjectParsed { 18530fdc8d8SChris Lattner public: 18630fdc8d8SChris Lattner // Constructors and Destructors 187b9c1b51eSKate Stone CommandObjectLogDisable(CommandInterpreter &interpreter) 188b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log disable", 1897149fab4SCaroline Tice "Disable one or more log channel categories.", 190b9c1b51eSKate Stone nullptr) { 1917149fab4SCaroline Tice CommandArgumentEntry arg1; 1927149fab4SCaroline Tice CommandArgumentEntry arg2; 193405fe67fSCaroline Tice CommandArgumentData channel_arg; 1947149fab4SCaroline Tice CommandArgumentData category_arg; 195405fe67fSCaroline Tice 196405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 197405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 1987149fab4SCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 199405fe67fSCaroline Tice 200b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 201b9c1b51eSKate Stone // argument entry. 2027149fab4SCaroline Tice arg1.push_back(channel_arg); 2037149fab4SCaroline Tice 2047149fab4SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 2057149fab4SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 2067149fab4SCaroline Tice 2077149fab4SCaroline Tice arg2.push_back(category_arg); 208405fe67fSCaroline Tice 209405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 2107149fab4SCaroline Tice m_arguments.push_back(arg1); 2117149fab4SCaroline Tice m_arguments.push_back(arg2); 21230fdc8d8SChris Lattner } 21330fdc8d8SChris Lattner 21426cac3afSEugene Zelenko ~CommandObjectLogDisable() override = default; 21530fdc8d8SChris Lattner 2166ba63d88SRaphael Isemann void 2176ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 2186ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 2196ba63d88SRaphael Isemann CompleteEnableDisable(request); 2206ba63d88SRaphael Isemann } 2216ba63d88SRaphael Isemann 2225a988416SJim Ingham protected: 223b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 22411eb9c64SZachary Turner if (args.empty()) { 225b9c1b51eSKate Stone result.AppendErrorWithFormat( 226b9c1b51eSKate Stone "%s takes a log channel and one or more log types.\n", 227b9c1b51eSKate Stone m_cmd_name.c_str()); 228434b81d0SRaphael Isemann result.SetStatus(eReturnStatusFailed); 22911eb9c64SZachary Turner return false; 23011eb9c64SZachary Turner } 23111eb9c64SZachary Turner 232adcd0268SBenjamin Kramer const std::string channel = std::string(args[0].ref()); 23320ad3c40SCaroline Tice args.Shift(); // Shift off the channel 234fb0d22d6SPavel Labath if (channel == "all") { 235775588c0SPavel Labath Log::DisableAllLogChannels(); 2365fb8af40SPavel Labath result.SetStatus(eReturnStatusSuccessFinishNoResult); 237fb0d22d6SPavel Labath } else { 238775588c0SPavel Labath std::string error; 239775588c0SPavel Labath llvm::raw_string_ostream error_stream(error); 2405e336903SPavel Labath if (Log::DisableLogChannel(channel, args.GetArgumentArrayRef(), 241775588c0SPavel Labath error_stream)) 242fb0d22d6SPavel Labath result.SetStatus(eReturnStatusSuccessFinishNoResult); 243775588c0SPavel Labath result.GetErrorStream() << error_stream.str(); 24430fdc8d8SChris Lattner } 24530fdc8d8SChris Lattner return result.Succeeded(); 24630fdc8d8SChris Lattner } 24730fdc8d8SChris Lattner }; 24830fdc8d8SChris Lattner 249b9c1b51eSKate Stone class CommandObjectLogList : public CommandObjectParsed { 25030fdc8d8SChris Lattner public: 25130fdc8d8SChris Lattner // Constructors and Destructors 252b9c1b51eSKate Stone CommandObjectLogList(CommandInterpreter &interpreter) 253b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log list", 254b9c1b51eSKate Stone "List the log categories for one or more log " 255b9c1b51eSKate Stone "channels. If none specified, lists them all.", 256b9c1b51eSKate Stone nullptr) { 257405fe67fSCaroline Tice CommandArgumentEntry arg; 258405fe67fSCaroline Tice CommandArgumentData channel_arg; 259405fe67fSCaroline Tice 260405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 261405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 262405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatStar; 263405fe67fSCaroline Tice 264b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 265b9c1b51eSKate Stone // argument entry. 266405fe67fSCaroline Tice arg.push_back(channel_arg); 267405fe67fSCaroline Tice 268405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 269405fe67fSCaroline Tice m_arguments.push_back(arg); 27030fdc8d8SChris Lattner } 27130fdc8d8SChris Lattner 27226cac3afSEugene Zelenko ~CommandObjectLogList() override = default; 27330fdc8d8SChris Lattner 2746ba63d88SRaphael Isemann void 2756ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 2766ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 2776ba63d88SRaphael Isemann for (llvm::StringRef channel : Log::ListChannels()) 2786ba63d88SRaphael Isemann request.TryCompleteCurrentArg(channel); 2796ba63d88SRaphael Isemann } 2806ba63d88SRaphael Isemann 2815a988416SJim Ingham protected: 282b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 283775588c0SPavel Labath std::string output; 284775588c0SPavel Labath llvm::raw_string_ostream output_stream(output); 28511eb9c64SZachary Turner if (args.empty()) { 286775588c0SPavel Labath Log::ListAllLogChannels(output_stream); 28730fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 288b9c1b51eSKate Stone } else { 289fb0d22d6SPavel Labath bool success = true; 290fb0d22d6SPavel Labath for (const auto &entry : args.entries()) 291775588c0SPavel Labath success = 2920d9a201eSRaphael Isemann success && Log::ListChannelCategories(entry.ref(), output_stream); 293fb0d22d6SPavel Labath if (success) 29430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 29530fdc8d8SChris Lattner } 296775588c0SPavel Labath result.GetOutputStream() << output_stream.str(); 29730fdc8d8SChris Lattner return result.Succeeded(); 29830fdc8d8SChris Lattner } 29930fdc8d8SChris Lattner }; 30030fdc8d8SChris Lattner 3011d3b7370SShu Anzai class CommandObjectLogTimerEnable : public CommandObjectParsed { 30230fdc8d8SChris Lattner public: 30330fdc8d8SChris Lattner // Constructors and Destructors 3041d3b7370SShu Anzai CommandObjectLogTimerEnable(CommandInterpreter &interpreter) 3051d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers enable", 3061d3b7370SShu Anzai "enable LLDB internal performance timers", 3071d3b7370SShu Anzai "log timers enable <depth>") { 3081d3b7370SShu Anzai CommandArgumentEntry arg; 3091d3b7370SShu Anzai CommandArgumentData depth_arg; 31030fdc8d8SChris Lattner 3111d3b7370SShu Anzai // Define the first (and only) variant of this arg. 3121d3b7370SShu Anzai depth_arg.arg_type = eArgTypeCount; 3131d3b7370SShu Anzai depth_arg.arg_repetition = eArgRepeatOptional; 3141d3b7370SShu Anzai 3151d3b7370SShu Anzai // There is only one variant this argument could be; put it into the 3161d3b7370SShu Anzai // argument entry. 3171d3b7370SShu Anzai arg.push_back(depth_arg); 3181d3b7370SShu Anzai 3191d3b7370SShu Anzai // Push the data for the first argument into the m_arguments vector. 3201d3b7370SShu Anzai m_arguments.push_back(arg); 3211d3b7370SShu Anzai } 3221d3b7370SShu Anzai 3231d3b7370SShu Anzai ~CommandObjectLogTimerEnable() override = default; 32430fdc8d8SChris Lattner 3255a988416SJim Ingham protected: 326b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 32730fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 32830fdc8d8SChris Lattner 3291d3b7370SShu Anzai if (args.GetArgumentCount() == 0) { 33030fdc8d8SChris Lattner Timer::SetDisplayDepth(UINT32_MAX); 33130fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 3321d3b7370SShu Anzai } else if (args.GetArgumentCount() == 1) { 33311eb9c64SZachary Turner uint32_t depth; 3341d3b7370SShu Anzai if (args[0].ref().consumeInteger(0, depth)) { 335b9c1b51eSKate Stone result.AppendError( 336b9c1b51eSKate Stone "Could not convert enable depth to an unsigned integer."); 33711eb9c64SZachary Turner } else { 33811eb9c64SZachary Turner Timer::SetDisplayDepth(depth); 33911eb9c64SZachary Turner result.SetStatus(eReturnStatusSuccessFinishNoResult); 340932725faSJim Ingham } 341932725faSJim Ingham } 342932725faSJim Ingham 343b9c1b51eSKate Stone if (!result.Succeeded()) { 34430fdc8d8SChris Lattner result.AppendError("Missing subcommand"); 34530fdc8d8SChris Lattner result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 34630fdc8d8SChris Lattner } 34730fdc8d8SChris Lattner return result.Succeeded(); 34830fdc8d8SChris Lattner } 34930fdc8d8SChris Lattner }; 35030fdc8d8SChris Lattner 3511d3b7370SShu Anzai class CommandObjectLogTimerDisable : public CommandObjectParsed { 3521d3b7370SShu Anzai public: 3531d3b7370SShu Anzai // Constructors and Destructors 3541d3b7370SShu Anzai CommandObjectLogTimerDisable(CommandInterpreter &interpreter) 3551d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers disable", 3561d3b7370SShu Anzai "disable LLDB internal performance timers", 3571d3b7370SShu Anzai nullptr) {} 3581d3b7370SShu Anzai 3591d3b7370SShu Anzai ~CommandObjectLogTimerDisable() override = default; 3601d3b7370SShu Anzai 3611d3b7370SShu Anzai protected: 3621d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 3631d3b7370SShu Anzai Timer::DumpCategoryTimes(&result.GetOutputStream()); 3641d3b7370SShu Anzai Timer::SetDisplayDepth(0); 3651d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 3661d3b7370SShu Anzai 3671d3b7370SShu Anzai if (!result.Succeeded()) { 3681d3b7370SShu Anzai result.AppendError("Missing subcommand"); 3691d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 3701d3b7370SShu Anzai } 3711d3b7370SShu Anzai return result.Succeeded(); 3721d3b7370SShu Anzai } 3731d3b7370SShu Anzai }; 3741d3b7370SShu Anzai 3751d3b7370SShu Anzai class CommandObjectLogTimerDump : public CommandObjectParsed { 3761d3b7370SShu Anzai public: 3771d3b7370SShu Anzai // Constructors and Destructors 3781d3b7370SShu Anzai CommandObjectLogTimerDump(CommandInterpreter &interpreter) 3791d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers dump", 3801d3b7370SShu Anzai "dump LLDB internal performance timers", nullptr) {} 3811d3b7370SShu Anzai 3821d3b7370SShu Anzai ~CommandObjectLogTimerDump() override = default; 3831d3b7370SShu Anzai 3841d3b7370SShu Anzai protected: 3851d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 3861d3b7370SShu Anzai Timer::DumpCategoryTimes(&result.GetOutputStream()); 3871d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 3881d3b7370SShu Anzai 3891d3b7370SShu Anzai if (!result.Succeeded()) { 3901d3b7370SShu Anzai result.AppendError("Missing subcommand"); 3911d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 3921d3b7370SShu Anzai } 3931d3b7370SShu Anzai return result.Succeeded(); 3941d3b7370SShu Anzai } 3951d3b7370SShu Anzai }; 3961d3b7370SShu Anzai 3971d3b7370SShu Anzai class CommandObjectLogTimerReset : public CommandObjectParsed { 3981d3b7370SShu Anzai public: 3991d3b7370SShu Anzai // Constructors and Destructors 4001d3b7370SShu Anzai CommandObjectLogTimerReset(CommandInterpreter &interpreter) 4011d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers reset", 4021d3b7370SShu Anzai "reset LLDB internal performance timers", nullptr) { 4031d3b7370SShu Anzai } 4041d3b7370SShu Anzai 4051d3b7370SShu Anzai ~CommandObjectLogTimerReset() override = default; 4061d3b7370SShu Anzai 4071d3b7370SShu Anzai protected: 4081d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 4091d3b7370SShu Anzai Timer::ResetCategoryTimes(); 4101d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 4111d3b7370SShu Anzai 4121d3b7370SShu Anzai if (!result.Succeeded()) { 4131d3b7370SShu Anzai result.AppendError("Missing subcommand"); 4141d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 4151d3b7370SShu Anzai } 4161d3b7370SShu Anzai return result.Succeeded(); 4171d3b7370SShu Anzai } 4181d3b7370SShu Anzai }; 4191d3b7370SShu Anzai 4201d3b7370SShu Anzai class CommandObjectLogTimerIncrement : public CommandObjectParsed { 4211d3b7370SShu Anzai public: 4221d3b7370SShu Anzai // Constructors and Destructors 4231d3b7370SShu Anzai CommandObjectLogTimerIncrement(CommandInterpreter &interpreter) 4241d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers increment", 4251d3b7370SShu Anzai "increment LLDB internal performance timers", 4261d3b7370SShu Anzai "log timers increment <bool>") { 4271d3b7370SShu Anzai CommandArgumentEntry arg; 4281d3b7370SShu Anzai CommandArgumentData bool_arg; 4291d3b7370SShu Anzai 4301d3b7370SShu Anzai // Define the first (and only) variant of this arg. 4311d3b7370SShu Anzai bool_arg.arg_type = eArgTypeBoolean; 4321d3b7370SShu Anzai bool_arg.arg_repetition = eArgRepeatPlain; 4331d3b7370SShu Anzai 4341d3b7370SShu Anzai // There is only one variant this argument could be; put it into the 4351d3b7370SShu Anzai // argument entry. 4361d3b7370SShu Anzai arg.push_back(bool_arg); 4371d3b7370SShu Anzai 4381d3b7370SShu Anzai // Push the data for the first argument into the m_arguments vector. 4391d3b7370SShu Anzai m_arguments.push_back(arg); 4401d3b7370SShu Anzai } 4411d3b7370SShu Anzai 4421d3b7370SShu Anzai ~CommandObjectLogTimerIncrement() override = default; 4431d3b7370SShu Anzai 4441d3b7370SShu Anzai void 4451d3b7370SShu Anzai HandleArgumentCompletion(CompletionRequest &request, 4461d3b7370SShu Anzai OptionElementVector &opt_element_vector) override { 4471d3b7370SShu Anzai request.TryCompleteCurrentArg("true"); 4481d3b7370SShu Anzai request.TryCompleteCurrentArg("false"); 4491d3b7370SShu Anzai } 4501d3b7370SShu Anzai 4511d3b7370SShu Anzai protected: 4521d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 4531d3b7370SShu Anzai result.SetStatus(eReturnStatusFailed); 4541d3b7370SShu Anzai 4551d3b7370SShu Anzai if (args.GetArgumentCount() == 1) { 4561d3b7370SShu Anzai bool success; 4571d3b7370SShu Anzai bool increment = 4581d3b7370SShu Anzai OptionArgParser::ToBoolean(args[0].ref(), false, &success); 4591d3b7370SShu Anzai 4601d3b7370SShu Anzai if (success) { 4611d3b7370SShu Anzai Timer::SetQuiet(!increment); 4621d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishNoResult); 4631d3b7370SShu Anzai } else 4641d3b7370SShu Anzai result.AppendError("Could not convert increment value to boolean."); 4651d3b7370SShu Anzai } 4661d3b7370SShu Anzai 4671d3b7370SShu Anzai if (!result.Succeeded()) { 4681d3b7370SShu Anzai result.AppendError("Missing subcommand"); 4691d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 4701d3b7370SShu Anzai } 4711d3b7370SShu Anzai return result.Succeeded(); 4721d3b7370SShu Anzai } 4731d3b7370SShu Anzai }; 4741d3b7370SShu Anzai 4751d3b7370SShu Anzai class CommandObjectLogTimer : public CommandObjectMultiword { 4761d3b7370SShu Anzai public: 4771d3b7370SShu Anzai CommandObjectLogTimer(CommandInterpreter &interpreter) 4781d3b7370SShu Anzai : CommandObjectMultiword(interpreter, "log timers", 4791d3b7370SShu Anzai "Enable, disable, dump, and reset LLDB internal " 4801d3b7370SShu Anzai "performance timers.", 4811d3b7370SShu Anzai "log timers < enable <depth> | disable | dump | " 4821d3b7370SShu Anzai "increment <bool> | reset >") { 4831d3b7370SShu Anzai LoadSubCommand("enable", CommandObjectSP( 4841d3b7370SShu Anzai new CommandObjectLogTimerEnable(interpreter))); 4851d3b7370SShu Anzai LoadSubCommand("disable", CommandObjectSP(new CommandObjectLogTimerDisable( 4861d3b7370SShu Anzai interpreter))); 4871d3b7370SShu Anzai LoadSubCommand("dump", 4881d3b7370SShu Anzai CommandObjectSP(new CommandObjectLogTimerDump(interpreter))); 4891d3b7370SShu Anzai LoadSubCommand( 4901d3b7370SShu Anzai "reset", CommandObjectSP(new CommandObjectLogTimerReset(interpreter))); 4911d3b7370SShu Anzai LoadSubCommand( 4921d3b7370SShu Anzai "increment", 4931d3b7370SShu Anzai CommandObjectSP(new CommandObjectLogTimerIncrement(interpreter))); 4941d3b7370SShu Anzai } 4951d3b7370SShu Anzai 4961d3b7370SShu Anzai ~CommandObjectLogTimer() override = default; 4971d3b7370SShu Anzai }; 4981d3b7370SShu Anzai 4997428a18cSKate Stone CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) 500b9c1b51eSKate Stone : CommandObjectMultiword(interpreter, "log", 501b9c1b51eSKate Stone "Commands controlling LLDB internal logging.", 502b9c1b51eSKate Stone "log <subcommand> [<command-options>]") { 503b9c1b51eSKate Stone LoadSubCommand("enable", 504b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogEnable(interpreter))); 505b9c1b51eSKate Stone LoadSubCommand("disable", 506b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogDisable(interpreter))); 507b9c1b51eSKate Stone LoadSubCommand("list", 508b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogList(interpreter))); 509b9c1b51eSKate Stone LoadSubCommand("timers", 510b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogTimer(interpreter))); 51130fdc8d8SChris Lattner } 51230fdc8d8SChris Lattner 51326cac3afSEugene Zelenko CommandObjectLog::~CommandObjectLog() = default; 514