Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lldb] Support frame recognizer regexp on mangled names. #105756

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lldb/include/lldb/Target/StackFrameRecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
};

Expand Down
54 changes: 35 additions & 19 deletions lldb/source/Commands/CommandObjectFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could be fancy and use an llvm::interleaveComma here

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)
Expand All @@ -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());
});
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions lldb/source/Target/AssertFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
23 changes: 14 additions & 9 deletions lldb/source/Target/StackFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
}
}
Copy link
Member

@vogelsgesang vogelsgesang Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaict, the matching in GetRecognizerForFrame also needs to be adjusted.

In #105695, you can find an implementation of pretty much the same idea. However, I implemented only GetRecognizerForFrame and skipped, e.g., ForEach

Copy link
Member

@vogelsgesang vogelsgesang Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to copy-paste / adjust whichever code from #105695 you might find useful. I will rebase that commit later on, after your changes landed. (I cannot land #105695 before #104523 gets re-applied, anyway)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah looks like we had the same idea!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let you commit your PR instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I relanded everything in 11d2de4.

Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Target/VerboseTrapFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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",
],
)
Expand All @@ -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(
Expand All @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion lldb/unittests/Target/StackFrameRecognizerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand Down
Loading