[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:06:02 PDT 2024


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

>From dcc5c787a7c146942fed66da5df01ef5a4401744 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           |  7 ++++
 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, 54 insertions(+), 29 deletions(-)

diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index 41d8eeef469eab..c815a073a5228f 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,12 @@ class Language : public PluginInterface {
   /// Python uses \b except. Defaults to \b catch.
   virtual llvm::StringRef GetCatchKeyword() const { return "catch"; }
 
+  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..7dbaf35fe8e8b6 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -171,6 +171,9 @@ class CPlusPlusLanguage : public Language {
 
   // PluginInterface protocol
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+  bool SymbolLookupHookShouldPruneResult(
+      const SymbolContext &sc, const Module::LookupInfo &lookup_info) override;
 };
 
 } // namespace lldb_private
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