Skip to content

[cherry-pick][lldb] Upstream frame recognizer fixes #9485

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

Merged
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
5 changes: 5 additions & 0 deletions lldb/include/lldb/Target/StackFrameRecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,13 @@ 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,
Mangled::NamePreference symbol_mangling,
bool first_instruction_only = true);

/// Add a new recognizer that triggers on a symbol regex.
Expand Down
62 changes: 33 additions & 29 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 @@ -906,7 +905,9 @@ void CommandObjectFrameRecognizerAdd::DoExecute(Args &command,
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 @@ -929,29 +930,31 @@ class CommandObjectFrameRecognizerClear : public CommandObjectParsed {
};

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

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;
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 {
Expand All @@ -974,13 +977,13 @@ class CommandObjectFrameRecognizerDelete : public CommandObjectParsed {
GetTarget().GetFrameRecognizerManager().ForEach(
[&request](uint32_t rid, std::string rname, std::string module,
llvm::ArrayRef<lldb_private::ConstString> symbols,
Mangled::NamePreference preference, bool regexp) {
Mangled::NamePreference symbol_mangling, bool regexp) {
StreamString strm;
if (rname.empty())
rname = "(internal)";

strm << rname;
PrintRecognizerDetails(strm, module, symbols, preference, regexp);
PrintRecognizerDetails(strm, rname, module, symbols, symbol_mangling,
regexp);

request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString());
});
Expand Down Expand Up @@ -1040,14 +1043,15 @@ class CommandObjectFrameRecognizerList : public CommandObjectParsed {
[&result,
&any_printed](uint32_t recognizer_id, std::string name,
std::string module, llvm::ArrayRef<ConstString> symbols,
Mangled::NamePreference preference, bool regexp) {
Mangled::NamePreference symbol_mangling, bool regexp) {
Stream &stream = result.GetOutputStream();

if (name.empty())
name = "(internal)";

stream << std::to_string(recognizer_id) << ": " << name;
PrintRecognizerDetails(stream, module, symbols, preference, regexp);
stream << std::to_string(recognizer_id) << ": ";
PrintRecognizerDetails(stream, name, module, symbols, symbol_mangling,
regexp);

stream.EOL();
stream.Flush();
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Commands/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ let Command = "thread backtrace" in {
def thread_backtrace_extended : Option<"extended", "e">, Group<1>,
Arg<"Boolean">, Desc<"Show the extended backtrace, if available">;
def thread_backtrace_unfiltered : Option<"unfiltered", "u">, Group<1>,
Desc<"Filter out frames according to installed frame recognizers">;
Desc<"Do not filter out frames according to installed frame recognizers">;
}

let Command = "thread step scope" in {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include <cstring>
#include <iostream>

#include <memory>

Expand Down Expand Up @@ -44,7 +45,7 @@ char CPPLanguageRuntime::ID = 0;
/// A frame recognizer that is installed to hide libc++ implementation
/// details from the backtrace.
class LibCXXFrameRecognizer : public StackFrameRecognizer {
RegularExpression m_hidden_function_regex;
std::array<RegularExpression, 4> m_hidden_regex;
RecognizedStackFrameSP m_hidden_frame;

struct LibCXXHiddenFrame : public RecognizedStackFrame {
Expand All @@ -53,10 +54,30 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer {

public:
LibCXXFrameRecognizer()
: m_hidden_function_regex(
R"(^std::__1::(__function.*::operator\(\)|__invoke))"
R"((\[.*\])?)" // ABI tag.
R"(( const)?$)"), // const.
: m_hidden_regex{
// internal implementation details of std::function
// std::__1::__function::__alloc_func<void (*)(), std::__1::allocator<void (*)()>, void ()>::operator()[abi:ne200000]
// std::__1::__function::__func<void (*)(), std::__1::allocator<void (*)()>, void ()>::operator()
// std::__1::__function::__value_func<void ()>::operator()[abi:ne200000]() const
RegularExpression{""
R"(^std::__[^:]*::)" // Namespace.
R"(__function::.*::operator\(\))"},
// internal implementation details of std::function in ABI v2
// std::__2::__function::__policy_invoker<void (int, int)>::__call_impl[abi:ne200000]<std::__2::__function::__default_alloc_func<int (*)(int, int), int (int, int)>>
RegularExpression{""
R"(^std::__[^:]*::)" // Namespace.
R"(__function::.*::__call_impl)"},
// internal implementation details of std::invoke
// std::__1::__invoke[abi:ne200000]<void (*&)()>
RegularExpression{
R"(^std::__[^:]*::)" // Namespace.
R"(__invoke)"},
// internal implementation details of std::invoke
// std::__1::__invoke_void_return_wrapper<void, true>::__call[abi:ne200000]<void (*&)()>
RegularExpression{
R"(^std::__[^:]*::)" // Namespace.
R"(__invoke_void_return_wrapper<.*>::__call)"}
},
m_hidden_frame(new LibCXXHiddenFrame()) {}

std::string GetName() override { return "libc++ frame recognizer"; }
Expand All @@ -69,8 +90,9 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer {
if (!sc.function)
return {};

if (m_hidden_function_regex.Execute(sc.function->GetNameNoArguments()))
return m_hidden_frame;
for (RegularExpression &r : m_hidden_regex)
if (r.Execute(sc.function->GetNameNoArguments()))
return m_hidden_frame;

return {};
}
Expand All @@ -81,9 +103,9 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
if (process)
process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
StackFrameRecognizerSP(new LibCXXFrameRecognizer()), {},
std::make_shared<RegularExpression>("^std::__1::"),
Mangled::NamePreference::ePreferDemangledWithoutArguments,
/*first_instruction_only*/ false);
std::make_shared<RegularExpression>("^std::__[^:]*::"),
/*mangling_preference=*/Mangled::ePreferDemangledWithoutArguments,
/*first_instruction_only=*/false);
}

bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
Expand All @@ -109,8 +131,7 @@ bool contains_lambda_identifier(llvm::StringRef &str_ref) {

CPPLanguageRuntime::LibCppStdFunctionCallableInfo
line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol,
llvm::StringRef first_template_param_sref,
bool has_invoke) {
llvm::StringRef first_template_param_sref, bool has_invoke) {

CPPLanguageRuntime::LibCppStdFunctionCallableInfo optional_info;

Expand Down Expand Up @@ -191,7 +212,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
ValueObjectSP sub_member_f_(member_f_->GetChildMemberWithName("__f_"));

if (sub_member_f_)
member_f_ = sub_member_f_;
member_f_ = sub_member_f_;
}

if (!member_f_)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3478,6 +3478,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 @@ -36,8 +36,9 @@ void RegisterAbortWithPayloadFrameRecognizer(Process *process) {
return;

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

RecognizedStackFrameSP
Expand Down
3 changes: 2 additions & 1 deletion 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,7 +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::ePreferMangled,
Mangled::ePreferDemangled,
/*first_instruction_only*/ false);
}

Expand Down
25 changes: 13 additions & 12 deletions lldb/source/Target/StackFrameRecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ 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(),
Mangled::NamePreference::ePreferMangled, first_instruction_only});
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(), symbol_mangling,
first_instruction_only});
BumpGeneration();
}

Expand All @@ -81,10 +82,10 @@ void StackFrameRecognizerManager::AddRecognizer(
}

void StackFrameRecognizerManager::ForEach(
const std::function<void(uint32_t, std::string, std::string,
llvm::ArrayRef<ConstString>,
Mangled::NamePreference, bool)> &callback) {
for (const auto &entry : m_recognizers) {
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;
std::string symbol_name;
Expand Down Expand Up @@ -130,7 +131,6 @@ StackFrameRecognizerSP
StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
const SymbolContext &symctx = frame->GetSymbolContext(
eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol);
ConstString function_name = symctx.GetFunctionName();
ModuleSP module_sp = symctx.module_sp;
if (!module_sp)
return StackFrameRecognizerSP();
Expand All @@ -150,13 +150,14 @@ StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
if (!entry.module_regexp->Execute(module_name.GetStringRef()))
continue;

ConstString function_name = symctx.GetFunctionName(entry.symbol_mangling);

if (!entry.symbols.empty())
if (!llvm::is_contained(entry.symbols, function_name))
continue;

if (entry.symbol_regexp)
if (!entry.symbol_regexp->Execute(
symctx.GetFunctionName(entry.symbol_mangling)))
if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
continue;

if (entry.first_instruction_only)
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 @@ -156,7 +156,7 @@ void RegisterVerboseTrapFrameRecognizer(Process &process) {

process.GetTarget().GetFrameRecognizerManager().AddRecognizer(
srf_recognizer_sp, module_regex_sp, symbol_regex_sp,
Mangled::ePreferMangled, false);
Mangled::ePreferDemangled, false);
}

} // namespace lldb_private
Loading