Skip to content

Commit f1088d6

Browse files
author
walter erquinigo
committed
[LLDB] Fix symbol breakpoint lookups for non-C-like languages
I'm developing the Mojo language, and some symbol breakpoints don't work because of two reasons that got fixed1: - There's a prune step that operates on the assuption that the symbol is C-like. That was discarding lots of the Mojo breakpoints - When finding functions for symbol breakpoints with eFunctionNameTypeFull, LLDB was only matching die.getMangledName() and not die.GetName(). The latter is the one useful for Mojo, because the former has some unreadable format in Mojo that is not exposed to the user. This shouldn't cause any regression for C-like languages, as the prune step would sanitize them anyway, but it's useful for languages like Mojo.
1 parent c4952e5 commit f1088d6

File tree

5 files changed

+63
-29
lines changed

5 files changed

+63
-29
lines changed

lldb/include/lldb/Target/Language.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <vector>
1717

1818
#include "lldb/Core/Highlighter.h"
19+
#include "lldb/Core/Module.h"
1920
#include "lldb/Core/PluginInterface.h"
2021
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
2122
#include "lldb/DataFormatters/FormatClasses.h"
@@ -379,6 +380,21 @@ class Language : public PluginInterface {
379380
/// Python uses \b except. Defaults to \b catch.
380381
virtual llvm::StringRef GetCatchKeyword() const { return "catch"; }
381382

383+
/// Method invoked by \a Module::LookupInfo::Prune used to filter out symbol
384+
/// search results.
385+
///
386+
/// \param[in] sc A symbol that passed the common symbol search lookup
387+
/// process.
388+
/// \param[in] lookup_info The full lookup info.
389+
///
390+
/// \return whether the given symbol should be discarded from the search
391+
/// results.
392+
virtual bool
393+
SymbolLookupHookShouldPruneResult(const SymbolContext &sc,
394+
const Module::LookupInfo &lookup_info) {
395+
return false;
396+
}
397+
382398
protected:
383399
// Classes that inherit from Language can see and modify these
384400

lldb/source/Core/Module.cpp

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -787,40 +787,16 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
787787
}
788788
}
789789

790-
// If we have only full name matches we might have tried to set breakpoint on
791-
// "func" and specified eFunctionNameTypeFull, but we might have found
792-
// "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
793-
// "func()" and "func" should end up matching.
794790
if (m_name_type_mask == eFunctionNameTypeFull) {
795791
SymbolContext sc;
796792
size_t i = start_idx;
797793
while (i < sc_list.GetSize()) {
798794
if (!sc_list.GetContextAtIndex(i, sc))
799795
break;
800-
// Make sure the mangled and demangled names don't match before we try to
801-
// pull anything out
802-
ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
803-
ConstString full_name(sc.GetFunctionName());
804-
if (mangled_name != m_name && full_name != m_name) {
805-
CPlusPlusLanguage::MethodName cpp_method(full_name);
806-
if (cpp_method.IsValid()) {
807-
if (cpp_method.GetContext().empty()) {
808-
if (cpp_method.GetBasename().compare(m_name) != 0) {
809-
sc_list.RemoveContextAtIndex(i);
810-
continue;
811-
}
812-
} else {
813-
std::string qualified_name;
814-
llvm::StringRef anon_prefix("(anonymous namespace)");
815-
if (cpp_method.GetContext() == anon_prefix)
816-
qualified_name = cpp_method.GetBasename().str();
817-
else
818-
qualified_name = cpp_method.GetScopeQualifiedName();
819-
if (qualified_name != m_name.GetCString()) {
820-
sc_list.RemoveContextAtIndex(i);
821-
continue;
822-
}
823-
}
796+
if (Language *languagePlugin = Language::FindPlugin(sc.GetLanguage())) {
797+
if (languagePlugin->SymbolLookupHookShouldPruneResult(sc, *this)) {
798+
sc_list.RemoveContextAtIndex(i);
799+
continue;
824800
}
825801
}
826802
++i;

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,3 +1759,41 @@ bool CPlusPlusLanguage::GetFunctionDisplayName(
17591759

17601760
return false;
17611761
}
1762+
1763+
bool CPlusPlusLanguage::SymbolLookupHookShouldPruneResult(
1764+
const SymbolContext &sc, const Module::LookupInfo &lookup_info) {
1765+
// If we have only full name matches we might have tried to set breakpoint on
1766+
// "func" and specified eFunctionNameTypeFull, but we might have found
1767+
// "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
1768+
// "func()" and "func" should end up matching.
1769+
// Make sure the mangled and demangled names don't match before we try to
1770+
// pull anything out
1771+
1772+
if (lookup_info.GetNameTypeMask() != eFunctionNameTypeFull)
1773+
return false;
1774+
1775+
ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
1776+
ConstString full_name(sc.GetFunctionName());
1777+
ConstString lookup_name = lookup_info.GetName();
1778+
if (mangled_name != lookup_name && full_name != lookup_name) {
1779+
CPlusPlusLanguage::MethodName cpp_method(full_name);
1780+
if (cpp_method.IsValid()) {
1781+
if (cpp_method.GetContext().empty()) {
1782+
if (cpp_method.GetBasename().compare(lookup_name) != 0) {
1783+
return true;
1784+
}
1785+
} else {
1786+
std::string qualified_name;
1787+
llvm::StringRef anon_prefix("(anonymous namespace)");
1788+
if (cpp_method.GetContext() == anon_prefix)
1789+
qualified_name = cpp_method.GetBasename().str();
1790+
else
1791+
qualified_name = cpp_method.GetScopeQualifiedName();
1792+
if (qualified_name != lookup_name.GetCString()) {
1793+
return true;
1794+
}
1795+
}
1796+
}
1797+
}
1798+
return false;
1799+
}

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ class CPlusPlusLanguage : public Language {
121121

122122
const Highlighter *GetHighlighter() const override { return &m_highlighter; }
123123

124+
bool SymbolLookupHookShouldPruneResult(
125+
const SymbolContext &sc, const Module::LookupInfo &lookup_info) override;
126+
124127
// Static Functions
125128
static void Initialize();
126129

lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ bool DWARFIndex::ProcessFunctionDIE(
5959
return true;
6060

6161
// In case of a full match, we just insert everything we find.
62-
if (name_type_mask & eFunctionNameTypeFull && die.GetMangledName() == name)
62+
if (name_type_mask & eFunctionNameTypeFull &&
63+
(die.GetMangledName() == name || die.GetName() == name))
6364
return callback(die);
6465

6566
// If looking for ObjC selectors, we need to also check if the name is a

0 commit comments

Comments
 (0)