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.", 48*abb0ed44SKazu Hirata nullptr) { 49ceb6b139SCaroline Tice CommandArgumentEntry arg1; 50ceb6b139SCaroline Tice CommandArgumentEntry arg2; 51405fe67fSCaroline Tice CommandArgumentData channel_arg; 52ceb6b139SCaroline Tice CommandArgumentData category_arg; 53405fe67fSCaroline Tice 54405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 55405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 56405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 57405fe67fSCaroline Tice 58b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 59b9c1b51eSKate Stone // argument entry. 60ceb6b139SCaroline Tice arg1.push_back(channel_arg); 61ceb6b139SCaroline Tice 62ceb6b139SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 63ceb6b139SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 64ceb6b139SCaroline Tice 65ceb6b139SCaroline Tice arg2.push_back(category_arg); 66405fe67fSCaroline Tice 67405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 68ceb6b139SCaroline Tice m_arguments.push_back(arg1); 69ceb6b139SCaroline Tice m_arguments.push_back(arg2); 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner 7226cac3afSEugene Zelenko ~CommandObjectLogEnable() override = default; 7330fdc8d8SChris Lattner 74b9c1b51eSKate Stone Options *GetOptions() override { return &m_options; } 7530fdc8d8SChris Lattner 76b9c1b51eSKate Stone class CommandOptions : public Options { 7730fdc8d8SChris Lattner public: 78*abb0ed44SKazu Hirata CommandOptions() {} 7930fdc8d8SChris Lattner 8026cac3afSEugene Zelenko ~CommandOptions() override = default; 8130fdc8d8SChris Lattner 8297206d57SZachary Turner Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 83b9c1b51eSKate Stone ExecutionContext *execution_context) override { 8497206d57SZachary Turner Status error; 853bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 8630fdc8d8SChris Lattner 87b9c1b51eSKate Stone switch (short_option) { 88b9c1b51eSKate Stone case 'f': 898f3be7a3SJonas Devlieghere log_file.SetFile(option_arg, FileSpec::Style::native); 908f3be7a3SJonas Devlieghere FileSystem::Instance().Resolve(log_file); 91b9c1b51eSKate Stone break; 92b9c1b51eSKate Stone case 't': 93b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_THREADSAFE; 94b9c1b51eSKate Stone break; 95b9c1b51eSKate Stone case 'v': 96b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_VERBOSE; 97b9c1b51eSKate Stone break; 98b9c1b51eSKate Stone case 's': 99b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE; 100b9c1b51eSKate Stone break; 101b9c1b51eSKate Stone case 'T': 102b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; 103b9c1b51eSKate Stone break; 104b9c1b51eSKate Stone case 'p': 105b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD; 106b9c1b51eSKate Stone break; 107b9c1b51eSKate Stone case 'n': 108b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 109b9c1b51eSKate Stone break; 110b9c1b51eSKate Stone case 'S': 111b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_BACKTRACE; 112b9c1b51eSKate Stone break; 113b9c1b51eSKate Stone case 'a': 114b9c1b51eSKate Stone log_options |= LLDB_LOG_OPTION_APPEND; 115b9c1b51eSKate Stone break; 116107d9bbdSPavel Labath case 'F': 117107d9bbdSPavel Labath log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION; 11890505a0aSPavel Labath break; 11930fdc8d8SChris Lattner default: 12036162014SRaphael Isemann llvm_unreachable("Unimplemented option"); 12130fdc8d8SChris Lattner } 12230fdc8d8SChris Lattner 12330fdc8d8SChris Lattner return error; 12430fdc8d8SChris Lattner } 12530fdc8d8SChris Lattner 126b9c1b51eSKate Stone void OptionParsingStarting(ExecutionContext *execution_context) override { 127889037d7SGreg Clayton log_file.Clear(); 12830fdc8d8SChris Lattner log_options = 0; 12930fdc8d8SChris Lattner } 13030fdc8d8SChris Lattner 1311f0f5b5bSZachary Turner llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 13270602439SZachary Turner return llvm::makeArrayRef(g_log_options); 1331f0f5b5bSZachary Turner } 13430fdc8d8SChris Lattner 13530fdc8d8SChris Lattner // Instance variables to hold the values for command options. 13630fdc8d8SChris Lattner 137889037d7SGreg Clayton FileSpec log_file; 1389494c510SJonas Devlieghere uint32_t log_options = 0; 13930fdc8d8SChris Lattner }; 14030fdc8d8SChris Lattner 1416ba63d88SRaphael Isemann void 1426ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 1436ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 1446ba63d88SRaphael Isemann CompleteEnableDisable(request); 1456ba63d88SRaphael Isemann } 1466ba63d88SRaphael Isemann 14730fdc8d8SChris Lattner protected: 148b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 149b9c1b51eSKate Stone if (args.GetArgumentCount() < 2) { 150b9c1b51eSKate Stone result.AppendErrorWithFormat( 151b9c1b51eSKate Stone "%s takes a log channel and one or more log types.\n", 152b9c1b51eSKate Stone m_cmd_name.c_str()); 15311eb9c64SZachary Turner return false; 15411eb9c64SZachary Turner } 15511eb9c64SZachary Turner 15611eb9c64SZachary Turner // Store into a std::string since we're about to shift the channel off. 157adcd0268SBenjamin Kramer const std::string channel = std::string(args[0].ref()); 1585a988416SJim Ingham args.Shift(); // Shift off the channel 159889037d7SGreg Clayton char log_file[PATH_MAX]; 160889037d7SGreg Clayton if (m_options.log_file) 161889037d7SGreg Clayton m_options.log_file.GetPath(log_file, sizeof(log_file)); 162889037d7SGreg Clayton else 163889037d7SGreg Clayton log_file[0] = '\0'; 164775588c0SPavel Labath 165775588c0SPavel Labath std::string error; 166775588c0SPavel Labath llvm::raw_string_ostream error_stream(error); 16757179860SJonas Devlieghere bool success = 16857179860SJonas Devlieghere GetDebugger().EnableLog(channel, args.GetArgumentArrayRef(), log_file, 16957179860SJonas Devlieghere m_options.log_options, error_stream); 170775588c0SPavel Labath result.GetErrorStream() << error_stream.str(); 171775588c0SPavel Labath 1725a988416SJim Ingham if (success) 1735a988416SJim Ingham result.SetStatus(eReturnStatusSuccessFinishNoResult); 1745a988416SJim Ingham else 1755a988416SJim Ingham result.SetStatus(eReturnStatusFailed); 1765a988416SJim Ingham return result.Succeeded(); 1775a988416SJim Ingham } 1785a988416SJim Ingham 17930fdc8d8SChris Lattner CommandOptions m_options; 18030fdc8d8SChris Lattner }; 18130fdc8d8SChris Lattner 182b9c1b51eSKate Stone class CommandObjectLogDisable : public CommandObjectParsed { 18330fdc8d8SChris Lattner public: 18430fdc8d8SChris Lattner // Constructors and Destructors 185b9c1b51eSKate Stone CommandObjectLogDisable(CommandInterpreter &interpreter) 186b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log disable", 1877149fab4SCaroline Tice "Disable one or more log channel categories.", 188b9c1b51eSKate Stone nullptr) { 1897149fab4SCaroline Tice CommandArgumentEntry arg1; 1907149fab4SCaroline Tice CommandArgumentEntry arg2; 191405fe67fSCaroline Tice CommandArgumentData channel_arg; 1927149fab4SCaroline Tice CommandArgumentData category_arg; 193405fe67fSCaroline Tice 194405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 195405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 1967149fab4SCaroline Tice channel_arg.arg_repetition = eArgRepeatPlain; 197405fe67fSCaroline Tice 198b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 199b9c1b51eSKate Stone // argument entry. 2007149fab4SCaroline Tice arg1.push_back(channel_arg); 2017149fab4SCaroline Tice 2027149fab4SCaroline Tice category_arg.arg_type = eArgTypeLogCategory; 2037149fab4SCaroline Tice category_arg.arg_repetition = eArgRepeatPlus; 2047149fab4SCaroline Tice 2057149fab4SCaroline Tice arg2.push_back(category_arg); 206405fe67fSCaroline Tice 207405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 2087149fab4SCaroline Tice m_arguments.push_back(arg1); 2097149fab4SCaroline Tice m_arguments.push_back(arg2); 21030fdc8d8SChris Lattner } 21130fdc8d8SChris Lattner 21226cac3afSEugene Zelenko ~CommandObjectLogDisable() override = default; 21330fdc8d8SChris Lattner 2146ba63d88SRaphael Isemann void 2156ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 2166ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 2176ba63d88SRaphael Isemann CompleteEnableDisable(request); 2186ba63d88SRaphael Isemann } 2196ba63d88SRaphael Isemann 2205a988416SJim Ingham protected: 221b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 22211eb9c64SZachary Turner if (args.empty()) { 223b9c1b51eSKate Stone result.AppendErrorWithFormat( 224b9c1b51eSKate Stone "%s takes a log channel and one or more log types.\n", 225b9c1b51eSKate Stone m_cmd_name.c_str()); 22611eb9c64SZachary Turner return false; 22711eb9c64SZachary Turner } 22811eb9c64SZachary Turner 229adcd0268SBenjamin Kramer const std::string channel = std::string(args[0].ref()); 23020ad3c40SCaroline Tice args.Shift(); // Shift off the channel 231fb0d22d6SPavel Labath if (channel == "all") { 232775588c0SPavel Labath Log::DisableAllLogChannels(); 2335fb8af40SPavel Labath result.SetStatus(eReturnStatusSuccessFinishNoResult); 234fb0d22d6SPavel Labath } else { 235775588c0SPavel Labath std::string error; 236775588c0SPavel Labath llvm::raw_string_ostream error_stream(error); 2375e336903SPavel Labath if (Log::DisableLogChannel(channel, args.GetArgumentArrayRef(), 238775588c0SPavel Labath error_stream)) 239fb0d22d6SPavel Labath result.SetStatus(eReturnStatusSuccessFinishNoResult); 240775588c0SPavel Labath result.GetErrorStream() << error_stream.str(); 24130fdc8d8SChris Lattner } 24230fdc8d8SChris Lattner return result.Succeeded(); 24330fdc8d8SChris Lattner } 24430fdc8d8SChris Lattner }; 24530fdc8d8SChris Lattner 246b9c1b51eSKate Stone class CommandObjectLogList : public CommandObjectParsed { 24730fdc8d8SChris Lattner public: 24830fdc8d8SChris Lattner // Constructors and Destructors 249b9c1b51eSKate Stone CommandObjectLogList(CommandInterpreter &interpreter) 250b9c1b51eSKate Stone : CommandObjectParsed(interpreter, "log list", 251b9c1b51eSKate Stone "List the log categories for one or more log " 252b9c1b51eSKate Stone "channels. If none specified, lists them all.", 253b9c1b51eSKate Stone nullptr) { 254405fe67fSCaroline Tice CommandArgumentEntry arg; 255405fe67fSCaroline Tice CommandArgumentData channel_arg; 256405fe67fSCaroline Tice 257405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 258405fe67fSCaroline Tice channel_arg.arg_type = eArgTypeLogChannel; 259405fe67fSCaroline Tice channel_arg.arg_repetition = eArgRepeatStar; 260405fe67fSCaroline Tice 261b9c1b51eSKate Stone // There is only one variant this argument could be; put it into the 262b9c1b51eSKate Stone // argument entry. 263405fe67fSCaroline Tice arg.push_back(channel_arg); 264405fe67fSCaroline Tice 265405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 266405fe67fSCaroline Tice m_arguments.push_back(arg); 26730fdc8d8SChris Lattner } 26830fdc8d8SChris Lattner 26926cac3afSEugene Zelenko ~CommandObjectLogList() override = default; 27030fdc8d8SChris Lattner 2716ba63d88SRaphael Isemann void 2726ba63d88SRaphael Isemann HandleArgumentCompletion(CompletionRequest &request, 2736ba63d88SRaphael Isemann OptionElementVector &opt_element_vector) override { 2746ba63d88SRaphael Isemann for (llvm::StringRef channel : Log::ListChannels()) 2756ba63d88SRaphael Isemann request.TryCompleteCurrentArg(channel); 2766ba63d88SRaphael Isemann } 2776ba63d88SRaphael Isemann 2785a988416SJim Ingham protected: 279b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 280775588c0SPavel Labath std::string output; 281775588c0SPavel Labath llvm::raw_string_ostream output_stream(output); 28211eb9c64SZachary Turner if (args.empty()) { 283775588c0SPavel Labath Log::ListAllLogChannels(output_stream); 28430fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 285b9c1b51eSKate Stone } else { 286fb0d22d6SPavel Labath bool success = true; 287fb0d22d6SPavel Labath for (const auto &entry : args.entries()) 288775588c0SPavel Labath success = 2890d9a201eSRaphael Isemann success && Log::ListChannelCategories(entry.ref(), output_stream); 290fb0d22d6SPavel Labath if (success) 29130fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishResult); 29230fdc8d8SChris Lattner } 293775588c0SPavel Labath result.GetOutputStream() << output_stream.str(); 29430fdc8d8SChris Lattner return result.Succeeded(); 29530fdc8d8SChris Lattner } 29630fdc8d8SChris Lattner }; 29730fdc8d8SChris Lattner 2981d3b7370SShu Anzai class CommandObjectLogTimerEnable : public CommandObjectParsed { 29930fdc8d8SChris Lattner public: 30030fdc8d8SChris Lattner // Constructors and Destructors 3011d3b7370SShu Anzai CommandObjectLogTimerEnable(CommandInterpreter &interpreter) 3021d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers enable", 3031d3b7370SShu Anzai "enable LLDB internal performance timers", 3041d3b7370SShu Anzai "log timers enable <depth>") { 3051d3b7370SShu Anzai CommandArgumentEntry arg; 3061d3b7370SShu Anzai CommandArgumentData depth_arg; 30730fdc8d8SChris Lattner 3081d3b7370SShu Anzai // Define the first (and only) variant of this arg. 3091d3b7370SShu Anzai depth_arg.arg_type = eArgTypeCount; 3101d3b7370SShu Anzai depth_arg.arg_repetition = eArgRepeatOptional; 3111d3b7370SShu Anzai 3121d3b7370SShu Anzai // There is only one variant this argument could be; put it into the 3131d3b7370SShu Anzai // argument entry. 3141d3b7370SShu Anzai arg.push_back(depth_arg); 3151d3b7370SShu Anzai 3161d3b7370SShu Anzai // Push the data for the first argument into the m_arguments vector. 3171d3b7370SShu Anzai m_arguments.push_back(arg); 3181d3b7370SShu Anzai } 3191d3b7370SShu Anzai 3201d3b7370SShu Anzai ~CommandObjectLogTimerEnable() override = default; 32130fdc8d8SChris Lattner 3225a988416SJim Ingham protected: 323b9c1b51eSKate Stone bool DoExecute(Args &args, CommandReturnObject &result) override { 32430fdc8d8SChris Lattner result.SetStatus(eReturnStatusFailed); 32530fdc8d8SChris Lattner 3261d3b7370SShu Anzai if (args.GetArgumentCount() == 0) { 32730fdc8d8SChris Lattner Timer::SetDisplayDepth(UINT32_MAX); 32830fdc8d8SChris Lattner result.SetStatus(eReturnStatusSuccessFinishNoResult); 3291d3b7370SShu Anzai } else if (args.GetArgumentCount() == 1) { 33011eb9c64SZachary Turner uint32_t depth; 3311d3b7370SShu Anzai if (args[0].ref().consumeInteger(0, depth)) { 332b9c1b51eSKate Stone result.AppendError( 333b9c1b51eSKate Stone "Could not convert enable depth to an unsigned integer."); 33411eb9c64SZachary Turner } else { 33511eb9c64SZachary Turner Timer::SetDisplayDepth(depth); 33611eb9c64SZachary Turner result.SetStatus(eReturnStatusSuccessFinishNoResult); 337932725faSJim Ingham } 338932725faSJim Ingham } 339932725faSJim Ingham 340b9c1b51eSKate Stone if (!result.Succeeded()) { 34130fdc8d8SChris Lattner result.AppendError("Missing subcommand"); 34230fdc8d8SChris Lattner result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 34330fdc8d8SChris Lattner } 34430fdc8d8SChris Lattner return result.Succeeded(); 34530fdc8d8SChris Lattner } 34630fdc8d8SChris Lattner }; 34730fdc8d8SChris Lattner 3481d3b7370SShu Anzai class CommandObjectLogTimerDisable : public CommandObjectParsed { 3491d3b7370SShu Anzai public: 3501d3b7370SShu Anzai // Constructors and Destructors 3511d3b7370SShu Anzai CommandObjectLogTimerDisable(CommandInterpreter &interpreter) 3521d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers disable", 3531d3b7370SShu Anzai "disable LLDB internal performance timers", 3541d3b7370SShu Anzai nullptr) {} 3551d3b7370SShu Anzai 3561d3b7370SShu Anzai ~CommandObjectLogTimerDisable() override = default; 3571d3b7370SShu Anzai 3581d3b7370SShu Anzai protected: 3591d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 3601d3b7370SShu Anzai Timer::DumpCategoryTimes(&result.GetOutputStream()); 3611d3b7370SShu Anzai Timer::SetDisplayDepth(0); 3621d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 3631d3b7370SShu Anzai 3641d3b7370SShu Anzai if (!result.Succeeded()) { 3651d3b7370SShu Anzai result.AppendError("Missing subcommand"); 3661d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 3671d3b7370SShu Anzai } 3681d3b7370SShu Anzai return result.Succeeded(); 3691d3b7370SShu Anzai } 3701d3b7370SShu Anzai }; 3711d3b7370SShu Anzai 3721d3b7370SShu Anzai class CommandObjectLogTimerDump : public CommandObjectParsed { 3731d3b7370SShu Anzai public: 3741d3b7370SShu Anzai // Constructors and Destructors 3751d3b7370SShu Anzai CommandObjectLogTimerDump(CommandInterpreter &interpreter) 3761d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers dump", 3771d3b7370SShu Anzai "dump LLDB internal performance timers", nullptr) {} 3781d3b7370SShu Anzai 3791d3b7370SShu Anzai ~CommandObjectLogTimerDump() override = default; 3801d3b7370SShu Anzai 3811d3b7370SShu Anzai protected: 3821d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 3831d3b7370SShu Anzai Timer::DumpCategoryTimes(&result.GetOutputStream()); 3841d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 3851d3b7370SShu Anzai 3861d3b7370SShu Anzai if (!result.Succeeded()) { 3871d3b7370SShu Anzai result.AppendError("Missing subcommand"); 3881d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 3891d3b7370SShu Anzai } 3901d3b7370SShu Anzai return result.Succeeded(); 3911d3b7370SShu Anzai } 3921d3b7370SShu Anzai }; 3931d3b7370SShu Anzai 3941d3b7370SShu Anzai class CommandObjectLogTimerReset : public CommandObjectParsed { 3951d3b7370SShu Anzai public: 3961d3b7370SShu Anzai // Constructors and Destructors 3971d3b7370SShu Anzai CommandObjectLogTimerReset(CommandInterpreter &interpreter) 3981d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers reset", 3991d3b7370SShu Anzai "reset LLDB internal performance timers", nullptr) { 4001d3b7370SShu Anzai } 4011d3b7370SShu Anzai 4021d3b7370SShu Anzai ~CommandObjectLogTimerReset() override = default; 4031d3b7370SShu Anzai 4041d3b7370SShu Anzai protected: 4051d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 4061d3b7370SShu Anzai Timer::ResetCategoryTimes(); 4071d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishResult); 4081d3b7370SShu Anzai 4091d3b7370SShu Anzai if (!result.Succeeded()) { 4101d3b7370SShu Anzai result.AppendError("Missing subcommand"); 4111d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 4121d3b7370SShu Anzai } 4131d3b7370SShu Anzai return result.Succeeded(); 4141d3b7370SShu Anzai } 4151d3b7370SShu Anzai }; 4161d3b7370SShu Anzai 4171d3b7370SShu Anzai class CommandObjectLogTimerIncrement : public CommandObjectParsed { 4181d3b7370SShu Anzai public: 4191d3b7370SShu Anzai // Constructors and Destructors 4201d3b7370SShu Anzai CommandObjectLogTimerIncrement(CommandInterpreter &interpreter) 4211d3b7370SShu Anzai : CommandObjectParsed(interpreter, "log timers increment", 4221d3b7370SShu Anzai "increment LLDB internal performance timers", 4231d3b7370SShu Anzai "log timers increment <bool>") { 4241d3b7370SShu Anzai CommandArgumentEntry arg; 4251d3b7370SShu Anzai CommandArgumentData bool_arg; 4261d3b7370SShu Anzai 4271d3b7370SShu Anzai // Define the first (and only) variant of this arg. 4281d3b7370SShu Anzai bool_arg.arg_type = eArgTypeBoolean; 4291d3b7370SShu Anzai bool_arg.arg_repetition = eArgRepeatPlain; 4301d3b7370SShu Anzai 4311d3b7370SShu Anzai // There is only one variant this argument could be; put it into the 4321d3b7370SShu Anzai // argument entry. 4331d3b7370SShu Anzai arg.push_back(bool_arg); 4341d3b7370SShu Anzai 4351d3b7370SShu Anzai // Push the data for the first argument into the m_arguments vector. 4361d3b7370SShu Anzai m_arguments.push_back(arg); 4371d3b7370SShu Anzai } 4381d3b7370SShu Anzai 4391d3b7370SShu Anzai ~CommandObjectLogTimerIncrement() override = default; 4401d3b7370SShu Anzai 4411d3b7370SShu Anzai void 4421d3b7370SShu Anzai HandleArgumentCompletion(CompletionRequest &request, 4431d3b7370SShu Anzai OptionElementVector &opt_element_vector) override { 4441d3b7370SShu Anzai request.TryCompleteCurrentArg("true"); 4451d3b7370SShu Anzai request.TryCompleteCurrentArg("false"); 4461d3b7370SShu Anzai } 4471d3b7370SShu Anzai 4481d3b7370SShu Anzai protected: 4491d3b7370SShu Anzai bool DoExecute(Args &args, CommandReturnObject &result) override { 4501d3b7370SShu Anzai result.SetStatus(eReturnStatusFailed); 4511d3b7370SShu Anzai 4521d3b7370SShu Anzai if (args.GetArgumentCount() == 1) { 4531d3b7370SShu Anzai bool success; 4541d3b7370SShu Anzai bool increment = 4551d3b7370SShu Anzai OptionArgParser::ToBoolean(args[0].ref(), false, &success); 4561d3b7370SShu Anzai 4571d3b7370SShu Anzai if (success) { 4581d3b7370SShu Anzai Timer::SetQuiet(!increment); 4591d3b7370SShu Anzai result.SetStatus(eReturnStatusSuccessFinishNoResult); 4601d3b7370SShu Anzai } else 4611d3b7370SShu Anzai result.AppendError("Could not convert increment value to boolean."); 4621d3b7370SShu Anzai } 4631d3b7370SShu Anzai 4641d3b7370SShu Anzai if (!result.Succeeded()) { 4651d3b7370SShu Anzai result.AppendError("Missing subcommand"); 4661d3b7370SShu Anzai result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str()); 4671d3b7370SShu Anzai } 4681d3b7370SShu Anzai return result.Succeeded(); 4691d3b7370SShu Anzai } 4701d3b7370SShu Anzai }; 4711d3b7370SShu Anzai 4721d3b7370SShu Anzai class CommandObjectLogTimer : public CommandObjectMultiword { 4731d3b7370SShu Anzai public: 4741d3b7370SShu Anzai CommandObjectLogTimer(CommandInterpreter &interpreter) 4751d3b7370SShu Anzai : CommandObjectMultiword(interpreter, "log timers", 4761d3b7370SShu Anzai "Enable, disable, dump, and reset LLDB internal " 4771d3b7370SShu Anzai "performance timers.", 4781d3b7370SShu Anzai "log timers < enable <depth> | disable | dump | " 4791d3b7370SShu Anzai "increment <bool> | reset >") { 4801d3b7370SShu Anzai LoadSubCommand("enable", CommandObjectSP( 4811d3b7370SShu Anzai new CommandObjectLogTimerEnable(interpreter))); 4821d3b7370SShu Anzai LoadSubCommand("disable", CommandObjectSP(new CommandObjectLogTimerDisable( 4831d3b7370SShu Anzai interpreter))); 4841d3b7370SShu Anzai LoadSubCommand("dump", 4851d3b7370SShu Anzai CommandObjectSP(new CommandObjectLogTimerDump(interpreter))); 4861d3b7370SShu Anzai LoadSubCommand( 4871d3b7370SShu Anzai "reset", CommandObjectSP(new CommandObjectLogTimerReset(interpreter))); 4881d3b7370SShu Anzai LoadSubCommand( 4891d3b7370SShu Anzai "increment", 4901d3b7370SShu Anzai CommandObjectSP(new CommandObjectLogTimerIncrement(interpreter))); 4911d3b7370SShu Anzai } 4921d3b7370SShu Anzai 4931d3b7370SShu Anzai ~CommandObjectLogTimer() override = default; 4941d3b7370SShu Anzai }; 4951d3b7370SShu Anzai 4967428a18cSKate Stone CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter) 497b9c1b51eSKate Stone : CommandObjectMultiword(interpreter, "log", 498b9c1b51eSKate Stone "Commands controlling LLDB internal logging.", 499b9c1b51eSKate Stone "log <subcommand> [<command-options>]") { 500b9c1b51eSKate Stone LoadSubCommand("enable", 501b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogEnable(interpreter))); 502b9c1b51eSKate Stone LoadSubCommand("disable", 503b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogDisable(interpreter))); 504b9c1b51eSKate Stone LoadSubCommand("list", 505b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogList(interpreter))); 506b9c1b51eSKate Stone LoadSubCommand("timers", 507b9c1b51eSKate Stone CommandObjectSP(new CommandObjectLogTimer(interpreter))); 50830fdc8d8SChris Lattner } 50930fdc8d8SChris Lattner 51026cac3afSEugene Zelenko CommandObjectLog::~CommandObjectLog() = default; 511