[Lldb-commits] [lldb] [lldb] Support frame recognizer regexp on mangled names. (PR #105756)
Adrian Prantl via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 22 17:41:29 PDT 2024
https://github.com/adrian-prantl created https://github.com/llvm/llvm-project/pull/105756
Instead of doing the coarse-grained initial matching of frame recognizers on fully demangled names, it can be much more efficient and reliable to filter on all functions of a particular language by discriminating on the mangled symbol name. This way a recognizer can be registered that should run on all functions of a particular language by matching on its mangling prefix(es).
>From c6f246a66b721df31003b7d2f8e32b5a2ca16a3f Mon Sep 17 00:00:00 2001
From: Adrian Prantl <aprantl at apple.com>
Date: Thu, 22 Aug 2024 17:35:01 -0700
Subject: [PATCH] [lldb] Support frame recognizer regexp on mangled names.
Instead of doing the coarse-grained initial matching of frame
recognizers on fully demangled names, it can be much more efficient
and reliable to filter on all functions of a particular language by
discriminating on the mangled symbol name. This way a recognizer can
be registered that should run on all functions of a particular
language by matching on its mangling prefix(es).
---
.../lldb/Target/StackFrameRecognizer.h | 9 +++-
lldb/source/Commands/CommandObjectFrame.cpp | 54 ++++++++++++-------
.../CPlusPlus/CPPLanguageRuntime.cpp | 1 +
lldb/source/Target/AssertFrameRecognizer.cpp | 1 +
lldb/source/Target/StackFrameRecognizer.cpp | 23 ++++----
.../Target/VerboseTrapFrameRecognizer.cpp | 3 +-
.../frame/recognizer/TestFrameRecognizer.py | 6 +--
.../Target/StackFrameRecognizerTest.cpp | 3 +-
8 files changed, 66 insertions(+), 34 deletions(-)
diff --git a/lldb/include/lldb/Target/StackFrameRecognizer.h b/lldb/include/lldb/Target/StackFrameRecognizer.h
index 8acebc12c4b1dc..a1757530870a02 100644
--- a/lldb/include/lldb/Target/StackFrameRecognizer.h
+++ b/lldb/include/lldb/Target/StackFrameRecognizer.h
@@ -109,15 +109,21 @@ class StackFrameRecognizerManager {
ConstString module, llvm::ArrayRef<ConstString> symbols,
bool first_instruction_only = true);
+ /// Add a new recognizer that triggers on a symbol regex.
+ ///
+ /// \param symbol_mangling controls whether the regex should apply
+ /// to the mangled or demangled name.
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
lldb::RegularExpressionSP module,
lldb::RegularExpressionSP symbol,
+ Mangled::NamePreference symbol_mangling,
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,
- bool regexp)> const &callback);
+ Mangled::NamePreference name_reference, bool regexp)> const
+ &callback);
bool RemoveRecognizerWithID(uint32_t recognizer_id);
@@ -142,6 +148,7 @@ class StackFrameRecognizerManager {
lldb::RegularExpressionSP module_regexp;
std::vector<ConstString> symbols;
lldb::RegularExpressionSP symbol_regexp;
+ Mangled::NamePreference symbol_mangling;
bool first_instruction_only;
};
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index 46c75e3dd159c0..2a9605d2072dae 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -899,7 +899,8 @@ void CommandObjectFrameRecognizerAdd::DoExecute(Args &command,
auto func =
RegularExpressionSP(new RegularExpression(m_options.m_symbols.front()));
GetTarget().GetFrameRecognizerManager().AddRecognizer(
- recognizer_sp, module, func, m_options.m_first_instruction_only);
+ recognizer_sp, module, func, Mangled::NamePreference::ePreferDemangled,
+ m_options.m_first_instruction_only);
} else {
auto module = ConstString(m_options.m_module);
std::vector<ConstString> symbols(m_options.m_symbols.begin(),
@@ -927,6 +928,32 @@ class CommandObjectFrameRecognizerClear : public CommandObjectParsed {
}
};
+static void
+PrintRecognizerDetails(Stream &strm, const std::string &module,
+ llvm::ArrayRef<lldb_private::ConstString> symbols,
+ Mangled::NamePreference preference, bool regexp) {
+ if (!module.empty())
+ strm << ", module " << module;
+ for (auto &symbol : symbols) {
+ strm << ", ";
+ if (!regexp)
+ strm << "symbol";
+ else
+ switch (preference) {
+ case Mangled::NamePreference ::ePreferMangled:
+ strm << "mangled symbol regexp";
+ break;
+ case Mangled::NamePreference ::ePreferDemangled:
+ strm << "demangled symbol regexp";
+ break;
+ case Mangled::NamePreference ::ePreferDemangledWithoutArguments:
+ strm << "demangled (no args) symbol regexp";
+ break;
+ }
+ strm << " " << symbol;
+ }
+}
+
class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
public:
CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter)
@@ -947,19 +974,13 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
GetTarget().GetFrameRecognizerManager().ForEach(
[&request](uint32_t rid, std::string rname, std::string module,
llvm::ArrayRef<lldb_private::ConstString> symbols,
- bool regexp) {
+ Mangled::NamePreference preference, bool regexp) {
StreamString strm;
if (rname.empty())
rname = "(internal)";
strm << rname;
- if (!module.empty())
- strm << ", module " << module;
- if (!symbols.empty())
- for (auto &symbol : symbols)
- strm << ", symbol " << symbol;
- if (regexp)
- strm << " (regexp)";
+ PrintRecognizerDetails(strm, module, symbols, preference, regexp);
request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString());
});
@@ -1016,22 +1037,17 @@ class CommandObjectFrameRecognizerList : public CommandObjectParsed {
void DoExecute(Args &command, CommandReturnObject &result) override {
bool any_printed = false;
GetTarget().GetFrameRecognizerManager().ForEach(
- [&result, &any_printed](
- uint32_t recognizer_id, std::string name, std::string module,
- llvm::ArrayRef<ConstString> symbols, bool regexp) {
+ [&result,
+ &any_printed](uint32_t recognizer_id, std::string name,
+ std::string module, llvm::ArrayRef<ConstString> symbols,
+ Mangled::NamePreference preference, bool regexp) {
Stream &stream = result.GetOutputStream();
if (name.empty())
name = "(internal)";
stream << std::to_string(recognizer_id) << ": " << name;
- if (!module.empty())
- stream << ", module " << module;
- if (!symbols.empty())
- for (auto &symbol : symbols)
- stream << ", symbol " << symbol;
- if (regexp)
- stream << " (regexp)";
+ PrintRecognizerDetails(stream, module, symbols, preference, regexp);
stream.EOL();
stream.Flush();
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index c60200ab186d09..a24cc884e5799c 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -82,6 +82,7 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
StackFrameRecognizerSP(new LibCXXFrameRecognizer()), {},
std::make_shared<RegularExpression>("^std::__1::"),
+ Mangled::NamePreference::ePreferDemangledWithoutArguments,
/*first_instruction_only*/ false);
}
diff --git a/lldb/source/Target/AssertFrameRecognizer.cpp b/lldb/source/Target/AssertFrameRecognizer.cpp
index da7c102645c014..1fc8f77d6f15ce 100644
--- a/lldb/source/Target/AssertFrameRecognizer.cpp
+++ b/lldb/source/Target/AssertFrameRecognizer.cpp
@@ -112,6 +112,7 @@ void RegisterAssertFrameRecognizer(Process *process) {
std::make_shared<AssertFrameRecognizer>(),
std::make_shared<RegularExpression>(std::move(module_re)),
std::make_shared<RegularExpression>(std::move(symbol_re)),
+ Mangled::ePreferMangled,
/*first_instruction_only*/ false);
}
diff --git a/lldb/source/Target/StackFrameRecognizer.cpp b/lldb/source/Target/StackFrameRecognizer.cpp
index 44411afc65dda9..2664c91fdc16d0 100644
--- a/lldb/source/Target/StackFrameRecognizer.cpp
+++ b/lldb/source/Target/StackFrameRecognizer.cpp
@@ -63,25 +63,28 @@ void StackFrameRecognizerManager::BumpGeneration() {
void StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP recognizer, ConstString module,
llvm::ArrayRef<ConstString> symbols, bool first_instruction_only) {
- m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,
- module, RegularExpressionSP(), symbols,
- RegularExpressionSP(), first_instruction_only});
+ m_recognizers.push_front(
+ {(uint32_t)m_recognizers.size(), recognizer, false, module,
+ RegularExpressionSP(), symbols, RegularExpressionSP(),
+ Mangled::NamePreference::ePreferMangled, first_instruction_only});
BumpGeneration();
}
void StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP recognizer, RegularExpressionSP module,
- RegularExpressionSP symbol, bool first_instruction_only) {
+ RegularExpressionSP symbol, Mangled::NamePreference symbol_mangling,
+ bool first_instruction_only) {
m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, true,
ConstString(), module, std::vector<ConstString>(),
- symbol, first_instruction_only});
+ symbol, symbol_mangling, first_instruction_only});
BumpGeneration();
}
void StackFrameRecognizerManager::ForEach(
const std::function<void(uint32_t, std::string, std::string,
- llvm::ArrayRef<ConstString>, bool)> &callback) {
- for (auto entry : m_recognizers) {
+ llvm::ArrayRef<ConstString>,
+ Mangled::NamePreference, bool)> &callback) {
+ for (const auto &entry : m_recognizers) {
if (entry.is_regexp) {
std::string module_name;
std::string symbol_name;
@@ -92,11 +95,13 @@ void StackFrameRecognizerManager::ForEach(
symbol_name = entry.symbol_regexp->GetText().str();
callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
- llvm::ArrayRef(ConstString(symbol_name)), true);
+ llvm::ArrayRef(ConstString(symbol_name)), entry.symbol_mangling,
+ true);
} else {
callback(entry.recognizer_id, entry.recognizer->GetName(),
- entry.module.GetCString(), entry.symbols, false);
+ entry.module.GetCString(), entry.symbols, entry.symbol_mangling,
+ false);
}
}
}
diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
index fe72c8aec570d3..3d20eb2136b5ad 100644
--- a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
+++ b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
@@ -116,7 +116,8 @@ void RegisterVerboseTrapFrameRecognizer(Process &process) {
std::make_shared<VerboseTrapFrameRecognizer>();
process.GetTarget().GetFrameRecognizerManager().AddRecognizer(
- srf_recognizer_sp, module_regex_sp, symbol_regex_sp, false);
+ srf_recognizer_sp, module_regex_sp, symbol_regex_sp,
+ Mangled::ePreferMangled, false);
}
} // namespace lldb_private
diff --git a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
index 6174ac61a709dd..df2ad60fddf088 100644
--- a/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
+++ b/lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
@@ -45,7 +45,7 @@ def test_frame_recognizer_1(self):
self.expect(
"frame recognizer list",
substrs=[
- "1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)",
+ "1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regexp bar",
"0: recognizer.MyFrameRecognizer, module a.out, symbol foo",
],
)
@@ -56,7 +56,7 @@ def test_frame_recognizer_1(self):
self.expect(
"frame recognizer list",
substrs=[
- "1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)"
+ "1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regexp bar"
],
)
self.expect(
@@ -79,7 +79,7 @@ def test_frame_recognizer_1(self):
self.expect(
"frame recognizer list",
substrs=[
- "1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)"
+ "1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regexp bar"
],
)
self.expect(
diff --git a/lldb/unittests/Target/StackFrameRecognizerTest.cpp b/lldb/unittests/Target/StackFrameRecognizerTest.cpp
index 695f091227d6a0..450e4babe0cd08 100644
--- a/lldb/unittests/Target/StackFrameRecognizerTest.cpp
+++ b/lldb/unittests/Target/StackFrameRecognizerTest.cpp
@@ -55,7 +55,7 @@ void RegisterDummyStackFrameRecognizer(StackFrameRecognizerManager &manager) {
StackFrameRecognizerSP dummy_recognizer_sp(new DummyStackFrameRecognizer());
manager.AddRecognizer(dummy_recognizer_sp, module_regex_sp, symbol_regex_sp,
- false);
+ Mangled::NamePreference::ePreferDemangled, false);
}
} // namespace
@@ -72,6 +72,7 @@ TEST_F(StackFrameRecognizerTest, NullModuleRegex) {
manager.ForEach([&any_printed](uint32_t recognizer_id, std::string name,
std::string function,
llvm::ArrayRef<ConstString> symbols,
+ Mangled::NamePreference preference,
bool regexp) { any_printed = true; });
EXPECT_TRUE(any_printed);
More information about the lldb-commits
mailing list