[Lldb-commits] [lldb] [lldb] Add support for disabling frame recognizers (PR #109219)
Adrian Vogelsgesang via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 18 16:32:45 PDT 2024
https://github.com/vogelsgesang created https://github.com/llvm/llvm-project/pull/109219
Sometimes you only want to temporarily disable a frame recognizer instead of deleting it. In particular, when dealing with one of the builtin frame recognizers, which cannot be restored after deletion.
>From c471c2fe615082fb9f9c5f39466bd47ec5b86bb0 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Wed, 18 Sep 2024 22:34:30 +0000
Subject: [PATCH] [lldb] Add support for disabling frame recognizers
Sometimes you only want to temporarily disable a frame recognizer
instead of deleting it. In particular, when dealing with one of the
builtin frame recognizers, which cannot be restored after deletion.
---
.../lldb/Target/StackFrameRecognizer.h | 7 +-
lldb/source/Commands/CommandObjectFrame.cpp | 144 +++++++++++++-----
lldb/source/Target/StackFrameRecognizer.cpp | 29 +++-
3 files changed, 131 insertions(+), 49 deletions(-)
diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h
index 617b1617d404a1..0deb4d46454784 100644
--- a/lldb/include/lldb/Target/StackFrameRecognizer.h
+++ b/lldb/include/lldb/Target/StackFrameRecognizer.h
@@ -125,11 +125,13 @@ class StackFrameRecognizerManager {
bool first_instruction_only = true);
void ForEach(std::function<
- void(uint32_t recognizer_id, std::string recognizer_name,
- std::string module, llvm::ArrayRef<ConstString> symbols,
+ void(uint32_t recognizer_id, bool enabled,
+ std::string recognizer_name, std::string module,
+ llvm::ArrayRef<ConstString> symbols,
Mangled::NamePreference name_reference, bool regexp)> const
&callback);
+ bool SetEnabledForID(uint32_t recognizer_id, bool enabled);
bool RemoveRecognizerWithID(uint32_t recognizer_id);
void RemoveAllRecognizers();
@@ -155,6 +157,7 @@ class StackFrameRecognizerManager {
lldb::RegularExpressionSP symbol_regexp;
Mangled::NamePreference symbol_mangling;
bool first_instruction_only;
+ bool enabled;
};
std::deque<RegisteredEntry> m_recognizers;
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index d8091e8993fde1..86db334ddc677e 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -31,8 +31,10 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Args.h"
+#include <iostream>
#include <memory>
#include <optional>
+#include <ostream>
#include <string>
using namespace lldb;
@@ -930,10 +932,13 @@ class CommandObjectFrameRecognizerClear : public CommandObjectParsed {
};
static void
-PrintRecognizerDetails(Stream &strm, const std::string &name,
+PrintRecognizerDetails(Stream &strm, const std::string &name, bool enabled,
const std::string &module,
llvm::ArrayRef<lldb_private::ConstString> symbols,
Mangled::NamePreference symbol_mangling, bool regexp) {
+ if (!enabled)
+ strm << "[disabled] ";
+
strm << name << ", ";
if (!module.empty())
@@ -957,53 +962,43 @@ PrintRecognizerDetails(Stream &strm, const std::string &name,
llvm::interleaveComma(symbols, strm);
}
-class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
-public:
- CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "frame recognizer delete",
- "Delete an existing frame recognizer by id.",
- nullptr) {
- AddSimpleArgumentList(eArgTypeRecognizerID);
- }
-
- ~CommandObjectFrameRecognizerDelete() override = default;
+// Base class for commands which accept a single frame recognizer as an argument
+class CommandObjectWithFrameRecognizerArg : public CommandObjectParsed {
+ public:
+ CommandObjectWithFrameRecognizerArg(CommandInterpreter &interpreter,
+ const char *name,
+ const char *help = nullptr,
+ const char *syntax = nullptr,
+ uint32_t flags = 0)
+ : CommandObjectParsed(interpreter, name, help, syntax, flags) {
+ AddSimpleArgumentList(eArgTypeRecognizerID);
+ }
void
HandleArgumentCompletion(CompletionRequest &request,
OptionElementVector &opt_element_vector) override {
+ std::cerr << request.GetCursorIndex() << std::endl;
if (request.GetCursorIndex() != 0)
return;
GetTarget().GetFrameRecognizerManager().ForEach(
- [&request](uint32_t rid, std::string rname, std::string module,
+ [&request](uint32_t rid, bool enabled, std::string rname, std::string module,
llvm::ArrayRef<lldb_private::ConstString> symbols,
Mangled::NamePreference symbol_mangling, bool regexp) {
StreamString strm;
if (rname.empty())
rname = "(internal)";
- PrintRecognizerDetails(strm, rname, module, symbols, symbol_mangling,
- regexp);
+ PrintRecognizerDetails(strm, rname, enabled, module, symbols,
+ symbol_mangling, regexp);
request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString());
});
}
-protected:
- void DoExecute(Args &command, CommandReturnObject &result) override {
- if (command.GetArgumentCount() == 0) {
- if (!m_interpreter.Confirm(
- "About to delete all frame recognizers, do you want to do that?",
- true)) {
- result.AppendMessage("Operation cancelled...");
- return;
- }
-
- GetTarget().GetFrameRecognizerManager().RemoveAllRecognizers();
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return;
- }
+ virtual void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id) = 0;
+ void DoExecute(Args &command, CommandReturnObject &result) override {
if (command.GetArgumentCount() != 1) {
result.AppendErrorWithFormat("'%s' takes zero or one arguments.\n",
m_cmd_name.c_str());
@@ -1017,10 +1012,73 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
return;
}
- if (!GetTarget().GetFrameRecognizerManager().RemoveRecognizerWithID(
- recognizer_id)) {
- result.AppendErrorWithFormat("'%s' is not a valid recognizer id.\n",
- command.GetArgumentAtIndex(0));
+ DoExecuteWithId(result, recognizer_id);
+ }
+};
+
+class CommandObjectFrameRecognizerEnable : public CommandObjectWithFrameRecognizerArg {
+public:
+ CommandObjectFrameRecognizerEnable(CommandInterpreter &interpreter)
+ : CommandObjectWithFrameRecognizerArg(
+ interpreter, "frame recognizer enable",
+ "Enable a frame recognizer by id.", nullptr) {
+ AddSimpleArgumentList(eArgTypeRecognizerID);
+ }
+
+ ~CommandObjectFrameRecognizerEnable() override = default;
+
+protected:
+ void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id) override {
+ auto& recognizer_mgr = GetTarget().GetFrameRecognizerManager();
+ if (!recognizer_mgr.SetEnabledForID(recognizer_id, true)) {
+ result.AppendErrorWithFormat("'%u' is not a valid recognizer id.\n",
+ recognizer_id);
+ return;
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+};
+
+class CommandObjectFrameRecognizerDisable : public CommandObjectWithFrameRecognizerArg {
+public:
+ CommandObjectFrameRecognizerDisable(CommandInterpreter &interpreter)
+ : CommandObjectWithFrameRecognizerArg(
+ interpreter, "frame recognizer disable",
+ "Disable a frame recognizer by id.", nullptr) {
+ AddSimpleArgumentList(eArgTypeRecognizerID);
+ }
+
+ ~CommandObjectFrameRecognizerDisable() override = default;
+
+protected:
+ void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id) override {
+ auto& recognizer_mgr = GetTarget().GetFrameRecognizerManager();
+ if (!recognizer_mgr.SetEnabledForID(recognizer_id, false)) {
+ result.AppendErrorWithFormat("'%u' is not a valid recognizer id.\n",
+ recognizer_id);
+ return;
+ }
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+};
+
+class CommandObjectFrameRecognizerDelete : public CommandObjectWithFrameRecognizerArg {
+public:
+ CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter)
+ : CommandObjectWithFrameRecognizerArg(
+ interpreter, "frame recognizer delete",
+ "Delete an existing frame recognizer by id.", nullptr) {
+ AddSimpleArgumentList(eArgTypeRecognizerID);
+ }
+
+ ~CommandObjectFrameRecognizerDelete() override = default;
+
+protected:
+ void DoExecuteWithId(CommandReturnObject &result, uint32_t recognizer_id) override {
+ auto& recognizer_mgr = GetTarget().GetFrameRecognizerManager();
+ if (!recognizer_mgr.RemoveRecognizerWithID(recognizer_id)) {
+ result.AppendErrorWithFormat("'%u' is not a valid recognizer id.\n",
+ recognizer_id);
return;
}
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -1041,7 +1099,7 @@ class CommandObjectFrameRecognizerList : public CommandObjectParsed {
bool any_printed = false;
GetTarget().GetFrameRecognizerManager().ForEach(
[&result,
- &any_printed](uint32_t recognizer_id, std::string name,
+ &any_printed](uint32_t recognizer_id, bool enabled, std::string name,
std::string module, llvm::ArrayRef<ConstString> symbols,
Mangled::NamePreference symbol_mangling, bool regexp) {
Stream &stream = result.GetOutputStream();
@@ -1050,7 +1108,7 @@ class CommandObjectFrameRecognizerList : public CommandObjectParsed {
name = "(internal)";
stream << std::to_string(recognizer_id) << ": ";
- PrintRecognizerDetails(stream, name, module, symbols, symbol_mangling,
+ PrintRecognizerDetails(stream, name, enabled, module, symbols, symbol_mangling,
regexp);
stream.EOL();
@@ -1135,18 +1193,24 @@ class CommandObjectFrameRecognizer : public CommandObjectMultiword {
interpreter, "frame recognizer",
"Commands for editing and viewing frame recognizers.",
"frame recognizer [<sub-command-options>] ") {
+ LoadSubCommand("info", CommandObjectSP(new CommandObjectFrameRecognizerInfo(
+ interpreter)));
+ LoadSubCommand("list", CommandObjectSP(new CommandObjectFrameRecognizerList(
+ interpreter)));
LoadSubCommand("add", CommandObjectSP(new CommandObjectFrameRecognizerAdd(
interpreter)));
LoadSubCommand(
- "clear",
- CommandObjectSP(new CommandObjectFrameRecognizerClear(interpreter)));
+ "enable",
+ CommandObjectSP(new CommandObjectFrameRecognizerEnable(interpreter)));
+ LoadSubCommand(
+ "disable",
+ CommandObjectSP(new CommandObjectFrameRecognizerDisable(interpreter)));
LoadSubCommand(
"delete",
CommandObjectSP(new CommandObjectFrameRecognizerDelete(interpreter)));
- LoadSubCommand("list", CommandObjectSP(new CommandObjectFrameRecognizerList(
- interpreter)));
- LoadSubCommand("info", CommandObjectSP(new CommandObjectFrameRecognizerInfo(
- interpreter)));
+ LoadSubCommand(
+ "clear",
+ CommandObjectSP(new CommandObjectFrameRecognizerClear(interpreter)));
}
~CommandObjectFrameRecognizer() override = default;
diff --git a/lldb/source/Target/StackFrameRecognizer.cpp b/lldb/source/Target/StackFrameRecognizer.cpp
index fa24253320a3f2..4592702942f8c9 100644
--- a/lldb/source/Target/StackFrameRecognizer.cpp
+++ b/lldb/source/Target/StackFrameRecognizer.cpp
@@ -67,7 +67,7 @@ void StackFrameRecognizerManager::AddRecognizer(
m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,
module, RegularExpressionSP(), symbols,
RegularExpressionSP(), symbol_mangling,
- first_instruction_only});
+ first_instruction_only, true});
BumpGeneration();
}
@@ -77,13 +77,14 @@ void StackFrameRecognizerManager::AddRecognizer(
bool first_instruction_only) {
m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, true,
ConstString(), module, std::vector<ConstString>(),
- symbol, symbol_mangling, first_instruction_only});
+ symbol, symbol_mangling, first_instruction_only,
+ true});
BumpGeneration();
}
void StackFrameRecognizerManager::ForEach(
const std::function<
- void(uint32_t, std::string, std::string, llvm::ArrayRef<ConstString>,
+ void(uint32_t, bool, std::string, std::string, llvm::ArrayRef<ConstString>,
Mangled::NamePreference name_reference, bool)> &callback) {
for (auto entry : m_recognizers) {
if (entry.is_regexp) {
@@ -95,22 +96,33 @@ void StackFrameRecognizerManager::ForEach(
if (entry.symbol_regexp)
symbol_name = entry.symbol_regexp->GetText().str();
- callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
+ callback(entry.recognizer_id, entry.enabled, entry.recognizer->GetName(), module_name,
llvm::ArrayRef(ConstString(symbol_name)), entry.symbol_mangling,
true);
} else {
- callback(entry.recognizer_id, entry.recognizer->GetName(),
+ callback(entry.recognizer_id, entry.enabled, entry.recognizer->GetName(),
entry.module.GetCString(), entry.symbols, entry.symbol_mangling,
false);
}
}
}
+bool StackFrameRecognizerManager::SetEnabledForID(uint32_t recognizer_id,
+ bool enabled) {
+ auto found =
+ llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {
+ return e.recognizer_id == recognizer_id;
+ });
+ if (found == m_recognizers.end())
+ return false;
+ found->enabled = enabled;
+ BumpGeneration();
+ return true;
+}
+
bool StackFrameRecognizerManager::RemoveRecognizerWithID(
uint32_t recognizer_id) {
- if (recognizer_id >= m_recognizers.size())
- return false;
auto found =
llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {
return e.recognizer_id == recognizer_id;
@@ -142,6 +154,9 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
Address current_addr = frame->GetFrameCodeAddress();
for (auto entry : m_recognizers) {
+ if (!entry.enabled)
+ continue;
+
if (entry.module)
if (entry.module != module_name)
continue;
More information about the lldb-commits
mailing list