15ffd83dbSDimitry Andric //===-- CommandObjectLog.cpp ----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "CommandObjectLog.h"
100b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
110b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h"
120b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
130b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
140b57cec5SDimitry Andric #include "lldb/Interpreter/Options.h"
150b57cec5SDimitry Andric #include "lldb/Utility/Args.h"
160b57cec5SDimitry Andric #include "lldb/Utility/FileSpec.h"
170b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
180b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
190b57cec5SDimitry Andric #include "lldb/Utility/Timer.h"
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric using namespace lldb;
220b57cec5SDimitry Andric using namespace lldb_private;
230b57cec5SDimitry Andric
249dba64beSDimitry Andric #define LLDB_OPTIONS_log
259dba64beSDimitry Andric #include "CommandOptions.inc"
269dba64beSDimitry Andric
279dba64beSDimitry Andric /// Common completion logic for log enable/disable.
CompleteEnableDisable(CompletionRequest & request)289dba64beSDimitry Andric static void CompleteEnableDisable(CompletionRequest &request) {
299dba64beSDimitry Andric size_t arg_index = request.GetCursorIndex();
309dba64beSDimitry Andric if (arg_index == 0) { // We got: log enable/disable x[tab]
319dba64beSDimitry Andric for (llvm::StringRef channel : Log::ListChannels())
329dba64beSDimitry Andric request.TryCompleteCurrentArg(channel);
339dba64beSDimitry Andric } else if (arg_index >= 1) { // We got: log enable/disable channel x[tab]
349dba64beSDimitry Andric llvm::StringRef channel = request.GetParsedLine().GetArgumentAtIndex(0);
359dba64beSDimitry Andric Log::ForEachChannelCategory(
369dba64beSDimitry Andric channel, [&request](llvm::StringRef name, llvm::StringRef desc) {
379dba64beSDimitry Andric request.TryCompleteCurrentArg(name, desc);
389dba64beSDimitry Andric });
399dba64beSDimitry Andric }
409dba64beSDimitry Andric }
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric class CommandObjectLogEnable : public CommandObjectParsed {
430b57cec5SDimitry Andric public:
440b57cec5SDimitry Andric // Constructors and Destructors
CommandObjectLogEnable(CommandInterpreter & interpreter)450b57cec5SDimitry Andric CommandObjectLogEnable(CommandInterpreter &interpreter)
460b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "log enable",
470b57cec5SDimitry Andric "Enable logging for a single log channel.",
480b57cec5SDimitry Andric nullptr),
490b57cec5SDimitry Andric m_options() {
500b57cec5SDimitry Andric CommandArgumentEntry arg1;
510b57cec5SDimitry Andric CommandArgumentEntry arg2;
520b57cec5SDimitry Andric CommandArgumentData channel_arg;
530b57cec5SDimitry Andric CommandArgumentData category_arg;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
560b57cec5SDimitry Andric channel_arg.arg_type = eArgTypeLogChannel;
570b57cec5SDimitry Andric channel_arg.arg_repetition = eArgRepeatPlain;
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
600b57cec5SDimitry Andric // argument entry.
610b57cec5SDimitry Andric arg1.push_back(channel_arg);
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric category_arg.arg_type = eArgTypeLogCategory;
640b57cec5SDimitry Andric category_arg.arg_repetition = eArgRepeatPlus;
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric arg2.push_back(category_arg);
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
690b57cec5SDimitry Andric m_arguments.push_back(arg1);
700b57cec5SDimitry Andric m_arguments.push_back(arg2);
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric ~CommandObjectLogEnable() override = default;
740b57cec5SDimitry Andric
GetOptions()750b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; }
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric class CommandOptions : public Options {
780b57cec5SDimitry Andric public:
CommandOptions()79*5f7ddb14SDimitry Andric CommandOptions() : Options(), log_file() {}
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric ~CommandOptions() override = default;
820b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)830b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
840b57cec5SDimitry Andric ExecutionContext *execution_context) override {
850b57cec5SDimitry Andric Status error;
860b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric switch (short_option) {
890b57cec5SDimitry Andric case 'f':
900b57cec5SDimitry Andric log_file.SetFile(option_arg, FileSpec::Style::native);
910b57cec5SDimitry Andric FileSystem::Instance().Resolve(log_file);
920b57cec5SDimitry Andric break;
930b57cec5SDimitry Andric case 't':
940b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_THREADSAFE;
950b57cec5SDimitry Andric break;
960b57cec5SDimitry Andric case 'v':
970b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_VERBOSE;
980b57cec5SDimitry Andric break;
990b57cec5SDimitry Andric case 's':
1000b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_PREPEND_SEQUENCE;
1010b57cec5SDimitry Andric break;
1020b57cec5SDimitry Andric case 'T':
1030b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP;
1040b57cec5SDimitry Andric break;
1050b57cec5SDimitry Andric case 'p':
1060b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;
1070b57cec5SDimitry Andric break;
1080b57cec5SDimitry Andric case 'n':
1090b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
1100b57cec5SDimitry Andric break;
1110b57cec5SDimitry Andric case 'S':
1120b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_BACKTRACE;
1130b57cec5SDimitry Andric break;
1140b57cec5SDimitry Andric case 'a':
1150b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_APPEND;
1160b57cec5SDimitry Andric break;
1170b57cec5SDimitry Andric case 'F':
1180b57cec5SDimitry Andric log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION;
1190b57cec5SDimitry Andric break;
1200b57cec5SDimitry Andric default:
1219dba64beSDimitry Andric llvm_unreachable("Unimplemented option");
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric return error;
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)1270b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
1280b57cec5SDimitry Andric log_file.Clear();
1290b57cec5SDimitry Andric log_options = 0;
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric
GetDefinitions()1320b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1330b57cec5SDimitry Andric return llvm::makeArrayRef(g_log_options);
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric // Instance variables to hold the values for command options.
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric FileSpec log_file;
139*5f7ddb14SDimitry Andric uint32_t log_options = 0;
1400b57cec5SDimitry Andric };
1410b57cec5SDimitry Andric
1429dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1439dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1449dba64beSDimitry Andric OptionElementVector &opt_element_vector) override {
1459dba64beSDimitry Andric CompleteEnableDisable(request);
1469dba64beSDimitry Andric }
1479dba64beSDimitry Andric
1480b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)1490b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
1500b57cec5SDimitry Andric if (args.GetArgumentCount() < 2) {
1510b57cec5SDimitry Andric result.AppendErrorWithFormat(
1520b57cec5SDimitry Andric "%s takes a log channel and one or more log types.\n",
1530b57cec5SDimitry Andric m_cmd_name.c_str());
1540b57cec5SDimitry Andric return false;
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric // Store into a std::string since we're about to shift the channel off.
1585ffd83dbSDimitry Andric const std::string channel = std::string(args[0].ref());
1590b57cec5SDimitry Andric args.Shift(); // Shift off the channel
1600b57cec5SDimitry Andric char log_file[PATH_MAX];
1610b57cec5SDimitry Andric if (m_options.log_file)
1620b57cec5SDimitry Andric m_options.log_file.GetPath(log_file, sizeof(log_file));
1630b57cec5SDimitry Andric else
1640b57cec5SDimitry Andric log_file[0] = '\0';
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric std::string error;
1670b57cec5SDimitry Andric llvm::raw_string_ostream error_stream(error);
1680b57cec5SDimitry Andric bool success =
1690b57cec5SDimitry Andric GetDebugger().EnableLog(channel, args.GetArgumentArrayRef(), log_file,
1700b57cec5SDimitry Andric m_options.log_options, error_stream);
1710b57cec5SDimitry Andric result.GetErrorStream() << error_stream.str();
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric if (success)
1740b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
1750b57cec5SDimitry Andric else
1760b57cec5SDimitry Andric result.SetStatus(eReturnStatusFailed);
1770b57cec5SDimitry Andric return result.Succeeded();
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric
1800b57cec5SDimitry Andric CommandOptions m_options;
1810b57cec5SDimitry Andric };
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andric class CommandObjectLogDisable : public CommandObjectParsed {
1840b57cec5SDimitry Andric public:
1850b57cec5SDimitry Andric // Constructors and Destructors
CommandObjectLogDisable(CommandInterpreter & interpreter)1860b57cec5SDimitry Andric CommandObjectLogDisable(CommandInterpreter &interpreter)
1870b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "log disable",
1880b57cec5SDimitry Andric "Disable one or more log channel categories.",
1890b57cec5SDimitry Andric nullptr) {
1900b57cec5SDimitry Andric CommandArgumentEntry arg1;
1910b57cec5SDimitry Andric CommandArgumentEntry arg2;
1920b57cec5SDimitry Andric CommandArgumentData channel_arg;
1930b57cec5SDimitry Andric CommandArgumentData category_arg;
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
1960b57cec5SDimitry Andric channel_arg.arg_type = eArgTypeLogChannel;
1970b57cec5SDimitry Andric channel_arg.arg_repetition = eArgRepeatPlain;
1980b57cec5SDimitry Andric
1990b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
2000b57cec5SDimitry Andric // argument entry.
2010b57cec5SDimitry Andric arg1.push_back(channel_arg);
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andric category_arg.arg_type = eArgTypeLogCategory;
2040b57cec5SDimitry Andric category_arg.arg_repetition = eArgRepeatPlus;
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric arg2.push_back(category_arg);
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
2090b57cec5SDimitry Andric m_arguments.push_back(arg1);
2100b57cec5SDimitry Andric m_arguments.push_back(arg2);
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric
2130b57cec5SDimitry Andric ~CommandObjectLogDisable() override = default;
2140b57cec5SDimitry Andric
2159dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)2169dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
2179dba64beSDimitry Andric OptionElementVector &opt_element_vector) override {
2189dba64beSDimitry Andric CompleteEnableDisable(request);
2199dba64beSDimitry Andric }
2209dba64beSDimitry Andric
2210b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)2220b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
2230b57cec5SDimitry Andric if (args.empty()) {
2240b57cec5SDimitry Andric result.AppendErrorWithFormat(
2250b57cec5SDimitry Andric "%s takes a log channel and one or more log types.\n",
2260b57cec5SDimitry Andric m_cmd_name.c_str());
2270b57cec5SDimitry Andric return false;
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric
2305ffd83dbSDimitry Andric const std::string channel = std::string(args[0].ref());
2310b57cec5SDimitry Andric args.Shift(); // Shift off the channel
2320b57cec5SDimitry Andric if (channel == "all") {
2330b57cec5SDimitry Andric Log::DisableAllLogChannels();
2340b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
2350b57cec5SDimitry Andric } else {
2360b57cec5SDimitry Andric std::string error;
2370b57cec5SDimitry Andric llvm::raw_string_ostream error_stream(error);
2380b57cec5SDimitry Andric if (Log::DisableLogChannel(channel, args.GetArgumentArrayRef(),
2390b57cec5SDimitry Andric error_stream))
2400b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
2410b57cec5SDimitry Andric result.GetErrorStream() << error_stream.str();
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric return result.Succeeded();
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric };
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric class CommandObjectLogList : public CommandObjectParsed {
2480b57cec5SDimitry Andric public:
2490b57cec5SDimitry Andric // Constructors and Destructors
CommandObjectLogList(CommandInterpreter & interpreter)2500b57cec5SDimitry Andric CommandObjectLogList(CommandInterpreter &interpreter)
2510b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "log list",
2520b57cec5SDimitry Andric "List the log categories for one or more log "
2530b57cec5SDimitry Andric "channels. If none specified, lists them all.",
2540b57cec5SDimitry Andric nullptr) {
2550b57cec5SDimitry Andric CommandArgumentEntry arg;
2560b57cec5SDimitry Andric CommandArgumentData channel_arg;
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
2590b57cec5SDimitry Andric channel_arg.arg_type = eArgTypeLogChannel;
2600b57cec5SDimitry Andric channel_arg.arg_repetition = eArgRepeatStar;
2610b57cec5SDimitry Andric
2620b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
2630b57cec5SDimitry Andric // argument entry.
2640b57cec5SDimitry Andric arg.push_back(channel_arg);
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
2670b57cec5SDimitry Andric m_arguments.push_back(arg);
2680b57cec5SDimitry Andric }
2690b57cec5SDimitry Andric
2700b57cec5SDimitry Andric ~CommandObjectLogList() override = default;
2710b57cec5SDimitry Andric
2729dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)2739dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
2749dba64beSDimitry Andric OptionElementVector &opt_element_vector) override {
2759dba64beSDimitry Andric for (llvm::StringRef channel : Log::ListChannels())
2769dba64beSDimitry Andric request.TryCompleteCurrentArg(channel);
2779dba64beSDimitry Andric }
2789dba64beSDimitry Andric
2790b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)2800b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
2810b57cec5SDimitry Andric std::string output;
2820b57cec5SDimitry Andric llvm::raw_string_ostream output_stream(output);
2830b57cec5SDimitry Andric if (args.empty()) {
2840b57cec5SDimitry Andric Log::ListAllLogChannels(output_stream);
2850b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
2860b57cec5SDimitry Andric } else {
2870b57cec5SDimitry Andric bool success = true;
2880b57cec5SDimitry Andric for (const auto &entry : args.entries())
2890b57cec5SDimitry Andric success =
2909dba64beSDimitry Andric success && Log::ListChannelCategories(entry.ref(), output_stream);
2910b57cec5SDimitry Andric if (success)
2920b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric result.GetOutputStream() << output_stream.str();
2950b57cec5SDimitry Andric return result.Succeeded();
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric };
2980b57cec5SDimitry Andric
2995ffd83dbSDimitry Andric class CommandObjectLogTimerEnable : public CommandObjectParsed {
3000b57cec5SDimitry Andric public:
3010b57cec5SDimitry Andric // Constructors and Destructors
CommandObjectLogTimerEnable(CommandInterpreter & interpreter)3025ffd83dbSDimitry Andric CommandObjectLogTimerEnable(CommandInterpreter &interpreter)
3035ffd83dbSDimitry Andric : CommandObjectParsed(interpreter, "log timers enable",
3045ffd83dbSDimitry Andric "enable LLDB internal performance timers",
3055ffd83dbSDimitry Andric "log timers enable <depth>") {
3065ffd83dbSDimitry Andric CommandArgumentEntry arg;
3075ffd83dbSDimitry Andric CommandArgumentData depth_arg;
3080b57cec5SDimitry Andric
3095ffd83dbSDimitry Andric // Define the first (and only) variant of this arg.
3105ffd83dbSDimitry Andric depth_arg.arg_type = eArgTypeCount;
3115ffd83dbSDimitry Andric depth_arg.arg_repetition = eArgRepeatOptional;
3125ffd83dbSDimitry Andric
3135ffd83dbSDimitry Andric // There is only one variant this argument could be; put it into the
3145ffd83dbSDimitry Andric // argument entry.
3155ffd83dbSDimitry Andric arg.push_back(depth_arg);
3165ffd83dbSDimitry Andric
3175ffd83dbSDimitry Andric // Push the data for the first argument into the m_arguments vector.
3185ffd83dbSDimitry Andric m_arguments.push_back(arg);
3195ffd83dbSDimitry Andric }
3205ffd83dbSDimitry Andric
3215ffd83dbSDimitry Andric ~CommandObjectLogTimerEnable() override = default;
3220b57cec5SDimitry Andric
3230b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)3240b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
3250b57cec5SDimitry Andric result.SetStatus(eReturnStatusFailed);
3260b57cec5SDimitry Andric
3275ffd83dbSDimitry Andric if (args.GetArgumentCount() == 0) {
3280b57cec5SDimitry Andric Timer::SetDisplayDepth(UINT32_MAX);
3290b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
3305ffd83dbSDimitry Andric } else if (args.GetArgumentCount() == 1) {
3310b57cec5SDimitry Andric uint32_t depth;
3325ffd83dbSDimitry Andric if (args[0].ref().consumeInteger(0, depth)) {
3330b57cec5SDimitry Andric result.AppendError(
3340b57cec5SDimitry Andric "Could not convert enable depth to an unsigned integer.");
3350b57cec5SDimitry Andric } else {
3360b57cec5SDimitry Andric Timer::SetDisplayDepth(depth);
3370b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric
3410b57cec5SDimitry Andric if (!result.Succeeded()) {
3420b57cec5SDimitry Andric result.AppendError("Missing subcommand");
3430b57cec5SDimitry Andric result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric return result.Succeeded();
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric };
3480b57cec5SDimitry Andric
3495ffd83dbSDimitry Andric class CommandObjectLogTimerDisable : public CommandObjectParsed {
3505ffd83dbSDimitry Andric public:
3515ffd83dbSDimitry Andric // Constructors and Destructors
CommandObjectLogTimerDisable(CommandInterpreter & interpreter)3525ffd83dbSDimitry Andric CommandObjectLogTimerDisable(CommandInterpreter &interpreter)
3535ffd83dbSDimitry Andric : CommandObjectParsed(interpreter, "log timers disable",
3545ffd83dbSDimitry Andric "disable LLDB internal performance timers",
3555ffd83dbSDimitry Andric nullptr) {}
3565ffd83dbSDimitry Andric
3575ffd83dbSDimitry Andric ~CommandObjectLogTimerDisable() override = default;
3585ffd83dbSDimitry Andric
3595ffd83dbSDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)3605ffd83dbSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
3615ffd83dbSDimitry Andric Timer::DumpCategoryTimes(&result.GetOutputStream());
3625ffd83dbSDimitry Andric Timer::SetDisplayDepth(0);
3635ffd83dbSDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
3645ffd83dbSDimitry Andric
3655ffd83dbSDimitry Andric if (!result.Succeeded()) {
3665ffd83dbSDimitry Andric result.AppendError("Missing subcommand");
3675ffd83dbSDimitry Andric result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
3685ffd83dbSDimitry Andric }
3695ffd83dbSDimitry Andric return result.Succeeded();
3705ffd83dbSDimitry Andric }
3715ffd83dbSDimitry Andric };
3725ffd83dbSDimitry Andric
3735ffd83dbSDimitry Andric class CommandObjectLogTimerDump : public CommandObjectParsed {
3745ffd83dbSDimitry Andric public:
3755ffd83dbSDimitry Andric // Constructors and Destructors
CommandObjectLogTimerDump(CommandInterpreter & interpreter)3765ffd83dbSDimitry Andric CommandObjectLogTimerDump(CommandInterpreter &interpreter)
3775ffd83dbSDimitry Andric : CommandObjectParsed(interpreter, "log timers dump",
3785ffd83dbSDimitry Andric "dump LLDB internal performance timers", nullptr) {}
3795ffd83dbSDimitry Andric
3805ffd83dbSDimitry Andric ~CommandObjectLogTimerDump() override = default;
3815ffd83dbSDimitry Andric
3825ffd83dbSDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)3835ffd83dbSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
3845ffd83dbSDimitry Andric Timer::DumpCategoryTimes(&result.GetOutputStream());
3855ffd83dbSDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
3865ffd83dbSDimitry Andric
3875ffd83dbSDimitry Andric if (!result.Succeeded()) {
3885ffd83dbSDimitry Andric result.AppendError("Missing subcommand");
3895ffd83dbSDimitry Andric result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
3905ffd83dbSDimitry Andric }
3915ffd83dbSDimitry Andric return result.Succeeded();
3925ffd83dbSDimitry Andric }
3935ffd83dbSDimitry Andric };
3945ffd83dbSDimitry Andric
3955ffd83dbSDimitry Andric class CommandObjectLogTimerReset : public CommandObjectParsed {
3965ffd83dbSDimitry Andric public:
3975ffd83dbSDimitry Andric // Constructors and Destructors
CommandObjectLogTimerReset(CommandInterpreter & interpreter)3985ffd83dbSDimitry Andric CommandObjectLogTimerReset(CommandInterpreter &interpreter)
3995ffd83dbSDimitry Andric : CommandObjectParsed(interpreter, "log timers reset",
4005ffd83dbSDimitry Andric "reset LLDB internal performance timers", nullptr) {
4015ffd83dbSDimitry Andric }
4025ffd83dbSDimitry Andric
4035ffd83dbSDimitry Andric ~CommandObjectLogTimerReset() override = default;
4045ffd83dbSDimitry Andric
4055ffd83dbSDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)4065ffd83dbSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
4075ffd83dbSDimitry Andric Timer::ResetCategoryTimes();
4085ffd83dbSDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
4095ffd83dbSDimitry Andric
4105ffd83dbSDimitry Andric if (!result.Succeeded()) {
4115ffd83dbSDimitry Andric result.AppendError("Missing subcommand");
4125ffd83dbSDimitry Andric result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
4135ffd83dbSDimitry Andric }
4145ffd83dbSDimitry Andric return result.Succeeded();
4155ffd83dbSDimitry Andric }
4165ffd83dbSDimitry Andric };
4175ffd83dbSDimitry Andric
4185ffd83dbSDimitry Andric class CommandObjectLogTimerIncrement : public CommandObjectParsed {
4195ffd83dbSDimitry Andric public:
4205ffd83dbSDimitry Andric // Constructors and Destructors
CommandObjectLogTimerIncrement(CommandInterpreter & interpreter)4215ffd83dbSDimitry Andric CommandObjectLogTimerIncrement(CommandInterpreter &interpreter)
4225ffd83dbSDimitry Andric : CommandObjectParsed(interpreter, "log timers increment",
4235ffd83dbSDimitry Andric "increment LLDB internal performance timers",
4245ffd83dbSDimitry Andric "log timers increment <bool>") {
4255ffd83dbSDimitry Andric CommandArgumentEntry arg;
4265ffd83dbSDimitry Andric CommandArgumentData bool_arg;
4275ffd83dbSDimitry Andric
4285ffd83dbSDimitry Andric // Define the first (and only) variant of this arg.
4295ffd83dbSDimitry Andric bool_arg.arg_type = eArgTypeBoolean;
4305ffd83dbSDimitry Andric bool_arg.arg_repetition = eArgRepeatPlain;
4315ffd83dbSDimitry Andric
4325ffd83dbSDimitry Andric // There is only one variant this argument could be; put it into the
4335ffd83dbSDimitry Andric // argument entry.
4345ffd83dbSDimitry Andric arg.push_back(bool_arg);
4355ffd83dbSDimitry Andric
4365ffd83dbSDimitry Andric // Push the data for the first argument into the m_arguments vector.
4375ffd83dbSDimitry Andric m_arguments.push_back(arg);
4385ffd83dbSDimitry Andric }
4395ffd83dbSDimitry Andric
4405ffd83dbSDimitry Andric ~CommandObjectLogTimerIncrement() override = default;
4415ffd83dbSDimitry Andric
4425ffd83dbSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)4435ffd83dbSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
4445ffd83dbSDimitry Andric OptionElementVector &opt_element_vector) override {
4455ffd83dbSDimitry Andric request.TryCompleteCurrentArg("true");
4465ffd83dbSDimitry Andric request.TryCompleteCurrentArg("false");
4475ffd83dbSDimitry Andric }
4485ffd83dbSDimitry Andric
4495ffd83dbSDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)4505ffd83dbSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
4515ffd83dbSDimitry Andric result.SetStatus(eReturnStatusFailed);
4525ffd83dbSDimitry Andric
4535ffd83dbSDimitry Andric if (args.GetArgumentCount() == 1) {
4545ffd83dbSDimitry Andric bool success;
4555ffd83dbSDimitry Andric bool increment =
4565ffd83dbSDimitry Andric OptionArgParser::ToBoolean(args[0].ref(), false, &success);
4575ffd83dbSDimitry Andric
4585ffd83dbSDimitry Andric if (success) {
4595ffd83dbSDimitry Andric Timer::SetQuiet(!increment);
4605ffd83dbSDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
4615ffd83dbSDimitry Andric } else
4625ffd83dbSDimitry Andric result.AppendError("Could not convert increment value to boolean.");
4635ffd83dbSDimitry Andric }
4645ffd83dbSDimitry Andric
4655ffd83dbSDimitry Andric if (!result.Succeeded()) {
4665ffd83dbSDimitry Andric result.AppendError("Missing subcommand");
4675ffd83dbSDimitry Andric result.AppendErrorWithFormat("Usage: %s\n", m_cmd_syntax.c_str());
4685ffd83dbSDimitry Andric }
4695ffd83dbSDimitry Andric return result.Succeeded();
4705ffd83dbSDimitry Andric }
4715ffd83dbSDimitry Andric };
4725ffd83dbSDimitry Andric
4735ffd83dbSDimitry Andric class CommandObjectLogTimer : public CommandObjectMultiword {
4745ffd83dbSDimitry Andric public:
CommandObjectLogTimer(CommandInterpreter & interpreter)4755ffd83dbSDimitry Andric CommandObjectLogTimer(CommandInterpreter &interpreter)
4765ffd83dbSDimitry Andric : CommandObjectMultiword(interpreter, "log timers",
4775ffd83dbSDimitry Andric "Enable, disable, dump, and reset LLDB internal "
4785ffd83dbSDimitry Andric "performance timers.",
4795ffd83dbSDimitry Andric "log timers < enable <depth> | disable | dump | "
4805ffd83dbSDimitry Andric "increment <bool> | reset >") {
4815ffd83dbSDimitry Andric LoadSubCommand("enable", CommandObjectSP(
4825ffd83dbSDimitry Andric new CommandObjectLogTimerEnable(interpreter)));
4835ffd83dbSDimitry Andric LoadSubCommand("disable", CommandObjectSP(new CommandObjectLogTimerDisable(
4845ffd83dbSDimitry Andric interpreter)));
4855ffd83dbSDimitry Andric LoadSubCommand("dump",
4865ffd83dbSDimitry Andric CommandObjectSP(new CommandObjectLogTimerDump(interpreter)));
4875ffd83dbSDimitry Andric LoadSubCommand(
4885ffd83dbSDimitry Andric "reset", CommandObjectSP(new CommandObjectLogTimerReset(interpreter)));
4895ffd83dbSDimitry Andric LoadSubCommand(
4905ffd83dbSDimitry Andric "increment",
4915ffd83dbSDimitry Andric CommandObjectSP(new CommandObjectLogTimerIncrement(interpreter)));
4925ffd83dbSDimitry Andric }
4935ffd83dbSDimitry Andric
4945ffd83dbSDimitry Andric ~CommandObjectLogTimer() override = default;
4955ffd83dbSDimitry Andric };
4965ffd83dbSDimitry Andric
CommandObjectLog(CommandInterpreter & interpreter)4970b57cec5SDimitry Andric CommandObjectLog::CommandObjectLog(CommandInterpreter &interpreter)
4980b57cec5SDimitry Andric : CommandObjectMultiword(interpreter, "log",
4990b57cec5SDimitry Andric "Commands controlling LLDB internal logging.",
5000b57cec5SDimitry Andric "log <subcommand> [<command-options>]") {
5010b57cec5SDimitry Andric LoadSubCommand("enable",
5020b57cec5SDimitry Andric CommandObjectSP(new CommandObjectLogEnable(interpreter)));
5030b57cec5SDimitry Andric LoadSubCommand("disable",
5040b57cec5SDimitry Andric CommandObjectSP(new CommandObjectLogDisable(interpreter)));
5050b57cec5SDimitry Andric LoadSubCommand("list",
5060b57cec5SDimitry Andric CommandObjectSP(new CommandObjectLogList(interpreter)));
5070b57cec5SDimitry Andric LoadSubCommand("timers",
5080b57cec5SDimitry Andric CommandObjectSP(new CommandObjectLogTimer(interpreter)));
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric
5110b57cec5SDimitry Andric CommandObjectLog::~CommandObjectLog() = default;
512