diff options
author | Adrian Vogelsgesang <avogelsgesang@salesforce.com> | 2024-08-27 19:15:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-27 19:15:42 +0200 |
commit | dd060bdede8edec18ad5ca122e15cc24a821e3fe (patch) | |
tree | ab6091e6c0c8781a992e8237d6d7e90131bdef0f /lldb/source/Commands/CommandObjectFrame.cpp | |
parent | 4baf29e81e30e6ebc1da56b9e5c338014961acf9 (diff) | |
download | llvm-dd060bdede8edec18ad5ca122e15cc24a821e3fe.zip llvm-dd060bdede8edec18ad5ca122e15cc24a821e3fe.tar.gz llvm-dd060bdede8edec18ad5ca122e15cc24a821e3fe.tar.bz2 |
[lldb] Add frame recognizers for libc++ `std::invoke` (#105695)
With this commit, we also hide the implementation details of
`std::invoke`. To do so, the `LibCXXFrameRecognizer` got a couple more
regular expressions.
The regular expression passed into `AddRecognizer` became problematic,
as it was evaluated on the demangled name. Those names also included
result types for C++ symbols. For `std::__invoke` the return type is a
huge `decltype(...)`, making the regular expresison really hard to
write.
Instead, I added support to `AddRecognizer` for matching on the
demangled names without result type and argument types.
By hiding the implementation details of `invoke`, also the back traces
for `std::function` become even nicer, because `std::function` is using
`__invoke` internally.
Co-authored-by: Adrian Prantl <aprantl@apple.com>
Diffstat (limited to 'lldb/source/Commands/CommandObjectFrame.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectFrame.cpp | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 46c75e3..ef57582 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -168,8 +168,7 @@ protected: // 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))); } @@ -899,13 +898,16 @@ 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 @@ -927,6 +929,34 @@ protected: } }; +static void +PrintRecognizerDetails(Stream &strm, const std::string &name, + const std::string &module, + llvm::ArrayRef<lldb_private::ConstString> symbols, + Mangled::NamePreference symbol_mangling, bool regexp) { + strm << name << ", "; + + 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) @@ -947,19 +977,13 @@ public: 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, rname, module, symbols, symbol_mangling, + regexp); request.TryCompleteCurrentArg(std::to_string(rid), strm.GetString()); }); @@ -1016,22 +1040,18 @@ protected: 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)"; + stream << std::to_string(recognizer_id) << ": "; + PrintRecognizerDetails(stream, name, module, symbols, symbol_mangling, + regexp); stream.EOL(); stream.Flush(); |