[Lldb-commits] [lldb] r334181 - DebugNamesDWARFIndex: Add ability to lookup variables

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu Jun 7 03:04:44 PDT 2018


Author: labath
Date: Thu Jun  7 03:04:44 2018
New Revision: 334181

URL: http://llvm.org/viewvc/llvm-project?rev=334181&view=rev
Log:
DebugNamesDWARFIndex: Add ability to lookup variables

Summary:
This patch adds the ability to lookup variables to the DWARF v5 index
class.

During review we discovered an inconsistency between how the existing
two indexes handle looking up qualified names of the variables:
- manual index would return a value if the input string exactly matched
  the demangled name of some variable.
- apple index ignored the context and returned any variable with the
  same base name.

So, this patch also rectifies that situation:
- it removes all context handling from the index classes. The
  GetGlobalVariables functions now just take a base name. For manual
  index, this meant we can stop putting demangled names into the
  variable index (this matches the behavior for functions).
- context extraction is put into SymbolFileDWARF, so that it is common
  to all indexes.
- additional filtering based on the context is also done in
  SymbolFileDWARF. This is done via a simple substring search, which is
  not ideal, but it matches what we are doing for functions (cf.
  Module::LookupInfo::Prune).

Reviewers: clayborg, JDevlieghere

Subscribers: aprantl, lldb-commits

Differential Revision: https://reviews.llvm.org/D47781

Added:
    lldb/trunk/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp
    lldb/trunk/lit/SymbolFile/DWARF/find-qualified-variable.cpp
Modified:
    lldb/trunk/lit/SymbolFile/DWARF/find-basic-variable.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Added: lldb/trunk/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp?rev=334181&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp (added)
+++ lldb/trunk/lit/SymbolFile/DWARF/dwarf5-index-is-used.cpp Thu Jun  7 03:04:44 2018
@@ -0,0 +1,14 @@
+// Test that we use the DWARF v5 name indexes.
+
+// REQUIRES: lld
+
+// RUN: clang %s -g -c -emit-llvm -o - --target=x86_64-pc-linux | \
+// RUN:   llc -accel-tables=Dwarf -filetype=obj -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: lldb-test symbols %t | FileCheck %s
+
+// CHECK: Name Index
+// CHECK: String: 0x{{.*}} "_start"
+// CHECK: Tag: DW_TAG_subprogram
+
+extern "C" void _start() {}

Modified: lldb/trunk/lit/SymbolFile/DWARF/find-basic-variable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/find-basic-variable.cpp?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/find-basic-variable.cpp (original)
+++ lldb/trunk/lit/SymbolFile/DWARF/find-basic-variable.cpp Thu Jun  7 03:04:44 2018
@@ -20,6 +20,18 @@
 // RUN:   FileCheck --check-prefix=REGEX %s
 // RUN: lldb-test symbols --name=not_there --find=variable %t | \
 // RUN:   FileCheck --check-prefix=EMPTY %s
+//
+// RUN: clang %s -g -c -emit-llvm -o - --target=x86_64-pc-linux | \
+// RUN:   llc -accel-tables=Dwarf -filetype=obj -o %t.o
+// RUN: ld.lld %t.o -o %t
+// RUN: lldb-test symbols --name=foo --find=variable --context=context %t | \
+// RUN:   FileCheck --check-prefix=CONTEXT %s
+// RUN: lldb-test symbols --name=foo --find=variable %t | \
+// RUN:   FileCheck --check-prefix=NAME %s
+// RUN: lldb-test symbols --regex --name=foo --find=variable %t | \
+// RUN:   FileCheck --check-prefix=REGEX %s
+// RUN: lldb-test symbols --name=not_there --find=variable %t | \
+// RUN:   FileCheck --check-prefix=EMPTY %s
 
 // EMPTY: Found 0 variables:
 // NAME: Found 4 variables:

Added: lldb/trunk/lit/SymbolFile/DWARF/find-qualified-variable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/find-qualified-variable.cpp?rev=334181&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/find-qualified-variable.cpp (added)
+++ lldb/trunk/lit/SymbolFile/DWARF/find-qualified-variable.cpp Thu Jun  7 03:04:44 2018
@@ -0,0 +1,15 @@
+// RUN: clang %s -g -c -o %t --target=x86_64-apple-macosx
+// RUN: lldb-test symbols --name=A::foo --find=variable %t | FileCheck %s
+
+// CHECK: Found 1 variables:
+
+struct A {
+  static int foo;
+};
+int A::foo;
+// NAME-DAG: name = "foo", {{.*}} decl = find-qualified-variable.cpp:[[@LINE-1]]
+
+struct B {
+  static int foo;
+};
+int B::foo;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp Thu Jun  7 03:04:44 2018
@@ -13,7 +13,6 @@
 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
 
-#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
 #include "Plugins/Language/ObjC/ObjCLanguage.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/Function.h"
@@ -56,19 +55,9 @@ std::unique_ptr<AppleDWARFIndex> AppleDW
   return nullptr;
 }
 
-void AppleDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) {
-  if (!m_apple_names_up)
-    return;
-
-  const char *name_cstr = name.GetCString();
-  llvm::StringRef basename;
-  llvm::StringRef context;
-
-  if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
-                                                      basename))
-    basename = name_cstr;
-
-  m_apple_names_up->FindByName(basename, offsets);
+void AppleDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
+  if (m_apple_names_up)
+    m_apple_names_up->FindByName(basename.GetStringRef(), offsets);
 }
 
 void AppleDWARFIndex::GetGlobalVariables(const RegularExpression &regex,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h Thu Jun  7 03:04:44 2018
@@ -33,7 +33,7 @@ public:
 
   void Preload() override {}
 
-  void GetGlobalVariables(ConstString name, DIEArray &offsets) override;
+  void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
   void GetGlobalVariables(const RegularExpression &regex,
                           DIEArray &offsets) override;
   void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFIndex.h Thu Jun  7 03:04:44 2018
@@ -25,7 +25,11 @@ public:
 
   virtual void Preload() = 0;
 
-  virtual void GetGlobalVariables(ConstString name, DIEArray &offsets) = 0;
+  /// Finds global variables with the given base name. Any additional filtering
+  /// (e.g., to only retrieve variables from a given context) should be done by
+  /// the consumer.
+  virtual void GetGlobalVariables(ConstString basename, DIEArray &offsets) = 0;
+
   virtual void GetGlobalVariables(const RegularExpression &regex,
                                   DIEArray &offsets) = 0;
   virtual void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) = 0;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp Thu Jun  7 03:04:44 2018
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h"
+#include "lldb/Utility/RegularExpression.h"
+#include "lldb/Utility/Stream.h"
 
 using namespace lldb_private;
 using namespace lldb;
@@ -23,11 +25,68 @@ llvm::Expected<std::unique_ptr<DebugName
 DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names,
                              DWARFDataExtractor debug_str,
                              DWARFDebugInfo *debug_info) {
-  auto index_up = llvm::make_unique<llvm::DWARFDebugNames>(ToLLVM(debug_names),
-                                                           ToLLVM(debug_str));
+  auto index_up =
+      llvm::make_unique<DebugNames>(ToLLVM(debug_names), ToLLVM(debug_str));
   if (llvm::Error E = index_up->extract())
     return std::move(E);
 
   return std::unique_ptr<DebugNamesDWARFIndex>(new DebugNamesDWARFIndex(
       module, std::move(index_up), debug_names, debug_str, debug_info));
 }
+
+void DebugNamesDWARFIndex::Append(const DebugNames::Entry &entry,
+                                  DIEArray &offsets) {
+  llvm::Optional<uint64_t> cu_offset = entry.getCUOffset();
+  llvm::Optional<uint64_t> die_offset = entry.getDIESectionOffset();
+  if (cu_offset && die_offset)
+    offsets.emplace_back(*cu_offset, *die_offset);
+}
+
+void DebugNamesDWARFIndex::MaybeLogLookupError(llvm::Error error,
+                                               const DebugNames::NameIndex &ni,
+                                               llvm::StringRef name) {
+  // Ignore SentinelErrors, log everything else.
+  LLDB_LOG_ERROR(
+      LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS),
+      handleErrors(std::move(error), [](const DebugNames::SentinelError &) {}),
+      "Failed to parse index entries for index at {1:x}, name {2}: {0}",
+      ni.getUnitOffset(), name);
+}
+
+void DebugNamesDWARFIndex::GetGlobalVariables(ConstString basename,
+                                              DIEArray &offsets) {
+  for (const DebugNames::Entry &entry :
+       m_debug_names_up->equal_range(basename.GetStringRef())) {
+    if (entry.tag() != DW_TAG_variable)
+      continue;
+
+    Append(entry, offsets);
+  }
+}
+
+void DebugNamesDWARFIndex::GetGlobalVariables(const RegularExpression &regex,
+                                              DIEArray &offsets) {
+  for (const DebugNames::NameIndex &ni: *m_debug_names_up) {
+    for (DebugNames::NameTableEntry nte: ni) {
+      if (!regex.Execute(nte.getString()))
+        continue;
+
+      uint32_t entry_offset = nte.getEntryOffset();
+      llvm::Expected<DebugNames::Entry> entry_or = ni.getEntry(&entry_offset);
+      for (; entry_or; entry_or = ni.getEntry(&entry_offset)) {
+        if (entry_or->tag() != DW_TAG_variable)
+          continue;
+
+        Append(*entry_or, offsets);
+      }
+      MaybeLogLookupError(entry_or.takeError(), ni, nte.getString());
+    }
+  }
+}
+
+void DebugNamesDWARFIndex::Dump(Stream &s) {
+  std::string data;
+  llvm::raw_string_ostream os(data);
+  m_debug_names_up->dump(os);
+  s.PutCString(os.str());
+}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h Thu Jun  7 03:04:44 2018
@@ -11,6 +11,7 @@
 #define LLDB_DEBUGNAMESDWARFINDEX_H
 
 #include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
 #include "lldb/Utility/ConstString.h"
 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
 
@@ -23,9 +24,9 @@ public:
 
   void Preload() override {}
 
-  void GetGlobalVariables(ConstString name, DIEArray &offsets) override {}
+  void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
   void GetGlobalVariables(const RegularExpression &regex,
-                          DIEArray &offsets) override {}
+                          DIEArray &offsets) override;
   void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override {}
   void GetObjCMethods(ConstString class_name, DIEArray &offsets) override {}
   void GetCompleteObjCClass(ConstString class_name, bool must_be_implementation,
@@ -42,7 +43,7 @@ public:
 
   void ReportInvalidDIEOffset(dw_offset_t offset,
                               llvm::StringRef name) override {}
-  void Dump(Stream &s) override {}
+  void Dump(Stream &s) override;
 
 private:
   DebugNamesDWARFIndex(Module &module,
@@ -57,7 +58,12 @@ private:
   DWARFDataExtractor m_debug_names_data;
   DWARFDataExtractor m_debug_str_data;
 
-  std::unique_ptr<llvm::DWARFDebugNames> m_debug_names_up;
+  using DebugNames = llvm::DWARFDebugNames;
+  std::unique_ptr<DebugNames> m_debug_names_up;
+
+  void Append(const DebugNames::Entry &entry, DIEArray &offsets);
+  void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni,
+                           llvm::StringRef name);
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp Thu Jun  7 03:04:44 2018
@@ -345,12 +345,8 @@ void ManualDWARFIndex::IndexUnitImpl(
         // entries
         if (mangled_cstr && name != mangled_cstr &&
             ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) {
-          Mangled mangled(ConstString(mangled_cstr), true);
-          set.globals.Insert(mangled.GetMangledName(),
+          set.globals.Insert(ConstString(mangled_cstr),
                              DIERef(cu_offset, die.GetOffset()));
-          ConstString demangled = mangled.GetDemangledName(cu_language);
-          if (demangled)
-            set.globals.Insert(demangled, DIERef(cu_offset, die.GetOffset()));
         }
       }
       break;
@@ -361,9 +357,9 @@ void ManualDWARFIndex::IndexUnitImpl(
   }
 }
 
-void ManualDWARFIndex::GetGlobalVariables(ConstString name, DIEArray &offsets) {
+void ManualDWARFIndex::GetGlobalVariables(ConstString basename, DIEArray &offsets) {
   Index();
-  m_set.globals.Find(name, offsets);
+  m_set.globals.Find(basename, offsets);
 }
 
 void ManualDWARFIndex::GetGlobalVariables(const RegularExpression &regex,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h Thu Jun  7 03:04:44 2018
@@ -21,7 +21,7 @@ public:
 
   void Preload() override { Index(); }
 
-  void GetGlobalVariables(ConstString name, DIEArray &offsets) override;
+  void GetGlobalVariables(ConstString basename, DIEArray &offsets) override;
   void GetGlobalVariables(const RegularExpression &regex,
                           DIEArray &offsets) override;
   void GetGlobalVariables(const DWARFUnit &cu, DIEArray &offsets) override;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=334181&r1=334180&r2=334181&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Thu Jun  7 03:04:44 2018
@@ -27,6 +27,7 @@
 #include "lldb/Utility/Timer.h"
 
 #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
 
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
@@ -2024,14 +2025,25 @@ uint32_t SymbolFileDWARF::FindGlobalVari
   // Remember how many variables are in the list before we search.
   const uint32_t original_size = variables.GetSize();
 
+  llvm::StringRef basename;
+  llvm::StringRef context;
+
+  if (!CPlusPlusLanguage::ExtractContextAndIdentifier(name.GetCString(),
+                                                      context, basename))
+    basename = name.GetStringRef();
+
   DIEArray die_offsets;
-  m_index->GetGlobalVariables(name, die_offsets);
+  m_index->GetGlobalVariables(ConstString(basename), die_offsets);
   const size_t num_die_matches = die_offsets.size();
   if (num_die_matches) {
     SymbolContext sc;
     sc.module_sp = m_obj_file->GetModule();
     assert(sc.module_sp);
 
+    // Loop invariant: Variables up to this index have been checked for context
+    // matches.
+    uint32_t pruned_idx = original_size;
+
     bool done = false;
     for (size_t i = 0; i < num_die_matches && !done; ++i) {
       const DIERef &die_ref = die_offsets[i];
@@ -2062,6 +2074,13 @@ uint32_t SymbolFileDWARF::FindGlobalVari
 
           ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false,
                          &variables);
+          while (pruned_idx < variables.GetSize()) {
+            VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx);
+            if (var_sp->GetName().GetStringRef().contains(name.GetStringRef()))
+              ++pruned_idx;
+            else
+              variables.RemoveVariableAtIndex(pruned_idx);
+          }
 
           if (variables.GetSize() - original_size >= max_matches)
             done = true;




More information about the lldb-commits mailing list