[Lldb-commits] [lldb] [LLDB] Fix symbol breakpoint lookups for non-C-like languages (PR #110543)

Walter Erquinigo via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 30 15:15:21 PDT 2024


https://github.com/walter-erquinigo updated https://github.com/llvm/llvm-project/pull/110543

>From 15132008232d446036a43a8ed3eed5883f80a2d5 Mon Sep 17 00:00:00 2001
From: walter erquinigo <walter at modular.com>
Date: Mon, 30 Sep 2024 13:33:35 -0400
Subject: [PATCH] [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.
---
 lldb/include/lldb/Target/Language.h           | 16 ++++++++
 lldb/source/Core/Module.cpp                   | 32 ++--------------
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  | 38 +++++++++++++++++++
 .../Language/CPlusPlus/CPlusPlusLanguage.h    |  3 ++
 .../Plugins/SymbolFile/DWARF/DWARFIndex.cpp   |  3 +-
 5 files changed, 63 insertions(+), 29 deletions(-)

diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index 41d8eeef469eab..f44f9fc08e7970 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "lldb/Core/Highlighter.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
 #include "lldb/DataFormatters/FormatClasses.h"
@@ -379,6 +380,21 @@ class Language : public PluginInterface {
   /// Python uses \b except. Defaults to \b catch.
   virtual llvm::StringRef GetCatchKeyword() const { return "catch"; }
 
+  /// Method invoked by \a Module::LookupInfo::Prune used to filter out symbol
+  /// search results.
+  ///
+  /// \param[in] sc A symbol that passed the common symbol search lookup
+  ///   process.
+  /// \param[in] lookup_info The full lookup info.
+  ///
+  /// \return whether the given symbol should be discarded from the search
+  /// results.
+  virtual bool
+  SymbolLookupHookShouldPruneResult(const SymbolContext &sc,
+                                    const Module::LookupInfo &lookup_info) {
+    return false;
+  }
+
 protected:
   // Classes that inherit from Language can see and modify these
 
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 88cc957e91fac4..0cc21c61a3dfa7 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -787,40 +787,16 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
     }
   }
 
-  // If we have only full name matches we might have tried to set breakpoint on
-  // "func" and specified eFunctionNameTypeFull, but we might have found
-  // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
-  // "func()" and "func" should end up matching.
   if (m_name_type_mask == eFunctionNameTypeFull) {
     SymbolContext sc;
     size_t i = start_idx;
     while (i < sc_list.GetSize()) {
       if (!sc_list.GetContextAtIndex(i, sc))
         break;
-      // Make sure the mangled and demangled names don't match before we try to
-      // pull anything out
-      ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
-      ConstString full_name(sc.GetFunctionName());
-      if (mangled_name != m_name && full_name != m_name) {
-        CPlusPlusLanguage::MethodName cpp_method(full_name);
-        if (cpp_method.IsValid()) {
-          if (cpp_method.GetContext().empty()) {
-            if (cpp_method.GetBasename().compare(m_name) != 0) {
-              sc_list.RemoveContextAtIndex(i);
-              continue;
-            }
-          } else {
-            std::string qualified_name;
-            llvm::StringRef anon_prefix("(anonymous namespace)");
-            if (cpp_method.GetContext() == anon_prefix)
-              qualified_name = cpp_method.GetBasename().str();
-            else
-              qualified_name = cpp_method.GetScopeQualifiedName();
-            if (qualified_name != m_name.GetCString()) {
-              sc_list.RemoveContextAtIndex(i);
-              continue;
-            }
-          }
+      if (Language *languagePlugin = Language::FindPlugin(sc.GetLanguage())) {
+        if (languagePlugin->SymbolLookupHookShouldPruneResult(sc, *this)) {
+          sc_list.RemoveContextAtIndex(i);
+          continue;
         }
       }
       ++i;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 06c827c2543f40..c2b07bdc3a3c65 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1759,3 +1759,41 @@ bool CPlusPlusLanguage::GetFunctionDisplayName(
 
   return false;
 }
+
+bool CPlusPlusLanguage::SymbolLookupHookShouldPruneResult(
+    const SymbolContext &sc, const Module::LookupInfo &lookup_info) {
+  // If we have only full name matches we might have tried to set breakpoint on
+  // "func" and specified eFunctionNameTypeFull, but we might have found
+  // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
+  // "func()" and "func" should end up matching.
+  // Make sure the mangled and demangled names don't match before we try to
+  // pull anything out
+
+  if (lookup_info.GetNameTypeMask() != eFunctionNameTypeFull)
+    return false;
+
+  ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
+  ConstString full_name(sc.GetFunctionName());
+  ConstString lookup_name = lookup_info.GetName();
+  if (mangled_name != lookup_name && full_name != lookup_name) {
+    CPlusPlusLanguage::MethodName cpp_method(full_name);
+    if (cpp_method.IsValid()) {
+      if (cpp_method.GetContext().empty()) {
+        if (cpp_method.GetBasename().compare(lookup_name) != 0) {
+          return false;
+        }
+      } else {
+        std::string qualified_name;
+        llvm::StringRef anon_prefix("(anonymous namespace)");
+        if (cpp_method.GetContext() == anon_prefix)
+          qualified_name = cpp_method.GetBasename().str();
+        else
+          qualified_name = cpp_method.GetScopeQualifiedName();
+        if (qualified_name != lookup_name.GetCString()) {
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 623d481bf117f4..edba8cb877f378 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -121,6 +121,9 @@ class CPlusPlusLanguage : public Language {
 
   const Highlighter *GetHighlighter() const override { return &m_highlighter; }
 
+  bool SymbolLookupHookShouldPruneResult(
+      const SymbolContext &sc, const Module::LookupInfo &lookup_info) override;
+
   // Static Functions
   static void Initialize();
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
index eafddbad03f57b..7bf53dce1b1b07 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
@@ -59,7 +59,8 @@ bool DWARFIndex::ProcessFunctionDIE(
     return true;
 
   // In case of a full match, we just insert everything we find.
-  if (name_type_mask & eFunctionNameTypeFull && die.GetMangledName() == name)
+  if (name_type_mask & eFunctionNameTypeFull &&
+      (die.GetMangledName() == name || die.GetName() == name))
     return callback(die);
 
   // If looking for ObjC selectors, we need to also check if the name is a



More information about the lldb-commits mailing list