Files
clang-p2996/lldb/source/Commands/CommandObjectStats.cpp
David Peixotto d4fe522eb4 Add commands to list/enable/disable plugins (#134418)
This commit adds three new commands for managing plugins. The `list`
command will show which plugins are currently registered and their
enabled state. The `enable` and `disable` commands can be used to enable
or disable plugins.

A disabled plugin will not show up to the PluginManager when it iterates
over available plugins of a particular type.

The purpose of these commands is to provide more visibility into
registered plugins and allow users to disable plugins for experimental
perf reasons.

There are a few limitations to the current implementation

1. Only SystemRuntime and InstrumentationRuntime plugins are currently
supported. We can easily extend the existing implementation to support
more types. The scope was limited to these plugins to keep the PR size
manageable.

2. Only "statically" know plugin types are supported (i.e. those managed
by the PluginManager and not from `plugin load`). It is possibly we
could support dynamic plugins as well, but I have not looked into it
yet.
2025-06-09 13:30:13 -07:00

172 lines
5.8 KiB
C++

//===-- CommandObjectStats.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "CommandObjectStats.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandOptionArgumentTable.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
class CommandObjectStatsEnable : public CommandObjectParsed {
public:
CommandObjectStatsEnable(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "enable",
"Enable statistics collection", nullptr,
eCommandProcessMustBePaused) {}
~CommandObjectStatsEnable() override = default;
protected:
void DoExecute(Args &command, CommandReturnObject &result) override {
if (DebuggerStats::GetCollectingStats()) {
result.AppendError("statistics already enabled");
return;
}
DebuggerStats::SetCollectingStats(true);
result.SetStatus(eReturnStatusSuccessFinishResult);
}
};
class CommandObjectStatsDisable : public CommandObjectParsed {
public:
CommandObjectStatsDisable(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "disable",
"Disable statistics collection", nullptr,
eCommandProcessMustBePaused) {}
~CommandObjectStatsDisable() override = default;
protected:
void DoExecute(Args &command, CommandReturnObject &result) override {
if (!DebuggerStats::GetCollectingStats()) {
result.AppendError("need to enable statistics before disabling them");
return;
}
DebuggerStats::SetCollectingStats(false);
result.SetStatus(eReturnStatusSuccessFinishResult);
}
};
#define LLDB_OPTIONS_statistics_dump
#include "CommandOptions.inc"
class CommandObjectStatsDump : public CommandObjectParsed {
class CommandOptions : public Options {
public:
CommandOptions() { OptionParsingStarting(nullptr); }
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) override {
Status error;
const int short_option = m_getopt_table[option_idx].val;
switch (short_option) {
case 'a':
m_all_targets = true;
break;
case 's':
m_stats_options.SetSummaryOnly(true);
break;
case 'f':
m_stats_options.SetLoadAllDebugInfo(true);
break;
case 'r':
if (llvm::Expected<bool> bool_or_error =
OptionArgParser::ToBoolean("--targets", option_arg))
m_stats_options.SetIncludeTargets(*bool_or_error);
else
error = Status::FromError(bool_or_error.takeError());
break;
case 'm':
if (llvm::Expected<bool> bool_or_error =
OptionArgParser::ToBoolean("--modules", option_arg))
m_stats_options.SetIncludeModules(*bool_or_error);
else
error = Status::FromError(bool_or_error.takeError());
break;
case 't':
if (llvm::Expected<bool> bool_or_error =
OptionArgParser::ToBoolean("--transcript", option_arg))
m_stats_options.SetIncludeTranscript(*bool_or_error);
else
error = Status::FromError(bool_or_error.takeError());
break;
case 'p':
if (llvm::Expected<bool> bool_or_error =
OptionArgParser::ToBoolean("--plugins", option_arg))
m_stats_options.SetIncludePlugins(*bool_or_error);
else
error = Status::FromError(bool_or_error.takeError());
break;
default:
llvm_unreachable("Unimplemented option");
}
return error;
}
void OptionParsingStarting(ExecutionContext *execution_context) override {
m_all_targets = false;
m_stats_options = StatisticsOptions();
}
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
return llvm::ArrayRef(g_statistics_dump_options);
}
const StatisticsOptions &GetStatisticsOptions() { return m_stats_options; }
bool m_all_targets = false;
StatisticsOptions m_stats_options = StatisticsOptions();
};
public:
CommandObjectStatsDump(CommandInterpreter &interpreter)
: CommandObjectParsed(
interpreter, "statistics dump", "Dump metrics in JSON format",
"statistics dump [<options>]", eCommandRequiresTarget) {}
~CommandObjectStatsDump() override = default;
Options *GetOptions() override { return &m_options; }
protected:
void DoExecute(Args &command, CommandReturnObject &result) override {
Target *target = nullptr;
if (!m_options.m_all_targets)
target = m_exe_ctx.GetTargetPtr();
result.AppendMessageWithFormatv(
"{0:2}", DebuggerStats::ReportStatistics(
GetDebugger(), target, m_options.GetStatisticsOptions()));
result.SetStatus(eReturnStatusSuccessFinishResult);
}
CommandOptions m_options;
};
CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
: CommandObjectMultiword(interpreter, "statistics",
"Print statistics about a debugging session",
"statistics <subcommand> [<subcommand-options>]") {
LoadSubCommand("enable",
CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
LoadSubCommand("disable",
CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
LoadSubCommand("dump",
CommandObjectSP(new CommandObjectStatsDump(interpreter)));
}
CommandObjectStats::~CommandObjectStats() = default;