Skip to content

Commit

Permalink
Copy additional content from adrian-prantl's commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vogelsgesang committed Aug 25, 2024
1 parent 32786ae commit e21f87c
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 65 deletions.
21 changes: 15 additions & 6 deletions lldb/include/lldb/Target/StackFrameRecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,21 +105,30 @@ class ScriptedStackFrameRecognizer : public StackFrameRecognizer {
/// Class that provides a registry of known stack frame recognizers.
class StackFrameRecognizerManager {
public:
/// Add a new recognizer that triggers on a given symbol name.
///
/// \param symbol_mangling controls whether the symbol name should be
/// compared to the mangled or demangled name.
void AddRecognizer(lldb::StackFrameRecognizerSP recognizer,
ConstString module, llvm::ArrayRef<ConstString> symbols,
bool first_instruction_only = true,
Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled);
Mangled::NamePreference symbol_mangling,
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,
bool first_instruction_only = true,
Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled);
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 @@ -144,8 +153,8 @@ class StackFrameRecognizerManager {
lldb::RegularExpressionSP module_regexp;
std::vector<ConstString> symbols;
lldb::RegularExpressionSP symbol_regexp;
Mangled::NamePreference symbol_mangling;
bool first_instruction_only;
Mangled::NamePreference mangling_preference;
};

std::deque<RegisteredEntry> m_recognizers;
Expand Down
64 changes: 40 additions & 24 deletions lldb/source/Commands/CommandObjectFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,7 @@ class CommandObjectFrameDiagnose : public CommandObjectParsed {
// We've already handled the case where the value object sp is null, so
// this is just to make sure future changes don't skip that:
assert(valobj_sp.get() && "Must have a valid ValueObject to print");
ValueObjectPrinter printer(*valobj_sp, &result.GetOutputStream(),
options);
ValueObjectPrinter printer(*valobj_sp, &result.GetOutputStream(), options);
if (llvm::Error error = printer.PrintValueObject())
result.AppendError(toString(std::move(error)));
}
Expand Down Expand Up @@ -899,13 +898,15 @@ 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(),
m_options.m_symbols.end());
GetTarget().GetFrameRecognizerManager().AddRecognizer(
recognizer_sp, module, symbols, m_options.m_first_instruction_only);
recognizer_sp, module, symbols, Mangled::NamePreference::ePreferDemangled,
m_options.m_first_instruction_only);
}
#endif

Expand All @@ -927,6 +928,31 @@ class CommandObjectFrameRecognizerClear : public CommandObjectParsed {
}
};

static void
PrintRecognizerDetails(Stream &strm, const std::string &module,
llvm::ArrayRef<lldb_private::ConstString> symbols,
Mangled::NamePreference symbol_mangling, bool regexp) {
if (!module.empty())
strm << ", module " << module;

switch (symbol_mangling) {
case Mangled::NamePreference ::ePreferMangled:
strm << "mangled symbol ";
break;
case Mangled::NamePreference ::ePreferDemangled:
strm << "demangled symbol ";
break;
case Mangled::NamePreference ::ePreferDemangledWithoutArguments:
strm << "demangled (no args) symbol ";
break;
}

if (regexp)
strm << "regex ";

llvm::interleaveComma(symbols, strm);
}

class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
public:
CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter)
Expand All @@ -947,19 +973,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 symbol_mangling, 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, symbol_mangling,
regexp);

request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString());
});
Expand Down Expand Up @@ -1016,22 +1036,18 @@ 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 symbol_mangling, 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, symbol_mangling,
regexp);

stream.EOL();
stream.Flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
StackFrameRecognizerSP(new LibCXXFrameRecognizer()), {},
std::make_shared<RegularExpression>("^std::__[0-9]*::"),
/*first_instruction_only=*/ false,
/*mangling_preference=*/ Mangled::ePreferDemangledWithoutArguments);
/*mangling_preference=*/Mangled::ePreferDemangledWithoutArguments,
/*first_instruction_only=*/false);
}

bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3465,6 +3465,6 @@ static void RegisterObjCExceptionRecognizer(Process *process) {

process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
module.GetFilename(), symbols,
module.GetFilename(), symbols, Mangled::NamePreference::ePreferDemangled,
/*first_instruction_only*/ true);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void RegisterAbortWithPayloadFrameRecognizer(Process *process) {

process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
std::make_shared<AbortWithPayloadFrameRecognizer>(), module_name,
sym_name, /*first_instruction_only*/ false);
sym_name, Mangled::NamePreference::ePreferDemangled, /*first_instruction_only*/ false);
}

RecognizedStackFrameSP
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Target/AssertFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ void RegisterAssertFrameRecognizer(Process *process) {
target.GetFrameRecognizerManager().AddRecognizer(
std::make_shared<AssertFrameRecognizer>(),
location.module_spec.GetFilename(), location.symbols,
Mangled::ePreferDemangled,
/*first_instruction_only*/ false);
return;
}
Expand All @@ -112,6 +113,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::ePreferDemangled,
/*first_instruction_only*/ false);
}

Expand Down
35 changes: 14 additions & 21 deletions lldb/source/Target/StackFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,28 +62,28 @@ void StackFrameRecognizerManager::BumpGeneration() {

void StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP recognizer, ConstString module,
llvm::ArrayRef<ConstString> symbols, bool first_instruction_only,
Mangled::NamePreference mangling_preference) {
llvm::ArrayRef<ConstString> symbols,
Mangled::NamePreference symbol_mangling, bool first_instruction_only) {
m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,
module, RegularExpressionSP(), symbols,
RegularExpressionSP(), first_instruction_only});
RegularExpressionSP(), symbol_mangling, first_instruction_only});
BumpGeneration();
}

void StackFrameRecognizerManager::AddRecognizer(
StackFrameRecognizerSP recognizer, RegularExpressionSP module,
RegularExpressionSP symbol, bool first_instruction_only,
Mangled::NamePreference mangling_preference) {
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,
mangling_preference});
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) {
const std::function<
void(uint32_t, std::string, std::string, llvm::ArrayRef<ConstString>,
Mangled::NamePreference name_reference, bool)> &callback) {
for (auto entry : m_recognizers) {
if (entry.is_regexp) {
std::string module_name;
Expand All @@ -95,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);
}
}
}
Expand Down Expand Up @@ -147,16 +149,7 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
if (!entry.module_regexp->Execute(module_name.GetStringRef()))
continue;

ConstString function_name = [&]() {
switch (entry.mangling_preference) {
case Mangled::ePreferMangled:
return symctx.GetFunctionName(entry.mangling_preference);
case Mangled::ePreferDemangled:
return symctx.GetFunctionName(entry.mangling_preference);
case Mangled::ePreferDemangledWithoutArguments:
return symctx.GetFunctionName(entry.mangling_preference);
}
}();
ConstString function_name = symctx.GetFunctionName(entry.symbol_mangling);

if (!entry.symbols.empty())
if (!llvm::is_contained(entry.symbols, function_name))
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Target/VerboseTrapFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ 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::ePreferDemangled, false);
}

} // namespace lldb_private
16 changes: 8 additions & 8 deletions lldb/test/API/commands/frame/recognizer/TestFrameRecognizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_frame_recognizer_1(self):

self.expect(
"frame recognizer list",
substrs=["0: recognizer.MyFrameRecognizer, module a.out, symbol foo"],
substrs=["0: recognizer.MyFrameRecognizer, module a.out, demangled symbol foo"],
)

self.runCmd(
Expand All @@ -45,8 +45,8 @@ def test_frame_recognizer_1(self):
self.expect(
"frame recognizer list",
substrs=[
"1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)",
"0: recognizer.MyFrameRecognizer, module a.out, symbol foo",
"1: recognizer.MyOtherFrameRecognizer, module a.out, demangled symbol regex bar",
"0: recognizer.MyFrameRecognizer, module a.out, demangled 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 bar (regexp)"
],
)
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 Expand Up @@ -224,7 +224,7 @@ def test_frame_recognizer_multi_symbol(self):
self.expect(
"frame recognizer list",
substrs=[
"recognizer.MyFrameRecognizer, module a.out, symbol foo, symbol bar"
"recognizer.MyFrameRecognizer, module a.out, demangled symbol foo, bar"
],
)

Expand Down Expand Up @@ -279,7 +279,7 @@ def test_frame_recognizer_target_specific(self):
self.expect(
"frame recognizer list",
substrs=[
"recognizer.MyFrameRecognizer, module a.out, symbol foo, symbol bar"
"recognizer.MyFrameRecognizer, module a.out, demangled symbol foo, bar"
],
)

Expand All @@ -305,7 +305,7 @@ def test_frame_recognizer_target_specific(self):

self.expect(
"frame recognizer list",
substrs=["recognizer.MyFrameRecognizer, module a.out, symbol bar"],
substrs=["recognizer.MyFrameRecognizer, module a.out, demangled symbol bar"],
)

# Now the new target should also recognize the frame.
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 symbol_mangling,
bool regexp) { any_printed = true; });

EXPECT_TRUE(any_printed);
Expand Down

0 comments on commit e21f87c

Please sign in to comment.