[Lldb-commits] [lldb] [lldb][NativePDB] Parse global variables. (PR #114303)

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 30 14:01:09 PDT 2024


https://github.com/ZequanWu created https://github.com/llvm/llvm-project/pull/114303

This doesn't parse S_CONSTANT case yet, because I found that `std::strong_ordering::equal` being a S_CONSTANT and has type of LF_STRUCTURE which is not currently handled when creating dwarf expression for the variable. Left a TODO for it to be finish later.

This makes `lldb/test/Shell/SymbolFile/PDB/ast-restore.test` passes on windows with native pdb plugin.


>From 215c36a380946a0c8cab63605bd0a9da13e642cd Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Tue, 29 Oct 2024 13:19:50 -0700
Subject: [PATCH] [lldb][NativePDB] Parse global variables.

---
 .../NativePDB/SymbolFileNativePDB.cpp         | 39 +++++++++++++++----
 .../NativePDB/SymbolFileNativePDB.h           |  1 +
 .../SymbolFile/NativePDB/ast-methods.cpp      |  5 ++-
 .../SymbolFile/NativePDB/global-ctor-dtor.cpp | 11 +++---
 .../Shell/SymbolFile/PDB/ast-restore.test     |  9 +----
 5 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 7fded6a31a3af5..3536599693cb46 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -365,18 +365,20 @@ void SymbolFileNativePDB::InitializeObject() {
 }
 
 uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() {
+  if (m_cu_count)
+    return *m_cu_count;
   const DbiModuleList &modules = m_index->dbi().modules();
-  uint32_t count = modules.getModuleCount();
-  if (count == 0)
-    return count;
+  m_cu_count = modules.getModuleCount();
+  if (*m_cu_count == 0)
+    return 0;
 
   // The linker can inject an additional "dummy" compilation unit into the
   // PDB. Ignore this special compile unit for our purposes, if it is there.
   // It is always the last one.
-  DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
+  DbiModuleDescriptor last = modules.getModuleDescriptor(*m_cu_count - 1);
   if (last.getModuleName() == "* Linker *")
-    --count;
-  return count;
+    --*m_cu_count;
+  return *m_cu_count;
 }
 
 Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
@@ -888,7 +890,8 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
 
   CompUnitSP comp_unit;
   std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);
-  if (!modi) {
+  // Some globals has modi points to the linker module, ignore them.
+  if (!modi || modi >= CalculateNumCompileUnits()) {
     return nullptr;
   }
 
@@ -1810,7 +1813,27 @@ SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
                                                   VariableList &variables) {
   PdbSymUid sym_uid(comp_unit.GetID());
   lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);
-  return 0;
+  for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
+    PdbGlobalSymId global{gid, false};
+    CVSymbol sym = m_index->ReadSymbolRecord(global);
+    // TODO: Handle S_CONSTANT which might be a record type (e.g.
+    // std::strong_ordering::equal). Currently
+    // lldb_private::npdb::MakeConstantLocationExpression doesn't handle this
+    // case and will crash if we do create global variables from it.
+    switch (sym.kind()) {
+    case SymbolKind::S_GDATA32:
+    case SymbolKind::S_LDATA32:
+    case SymbolKind::S_GTHREAD32:
+    case SymbolKind::S_LTHREAD32: {
+      if (VariableSP var = GetOrCreateGlobalVariable(global))
+        variables.AddVariable(var);
+      break;
+    }
+    default:
+      break;
+    }
+  }
+  return variables.GetSize();
 }
 
 VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 669c44aa131edc..6e384b2b17873f 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -265,6 +265,7 @@ class SymbolFileNativePDB : public SymbolFileCommon {
   // UID for anonymous union and anonymous struct as they don't have entities in
   // pdb debug info.
   lldb::user_id_t anonymous_id = LLDB_INVALID_UID - 1;
+  std::optional<uint32_t> m_cu_count = 0;
 
   std::unique_ptr<llvm::pdb::PDBFile> m_file_up;
   std::unique_ptr<PdbIndex> m_index;
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/ast-methods.cpp b/lldb/test/Shell/SymbolFile/NativePDB/ast-methods.cpp
index f2be33aae8163b..ff6e0ddb20f9eb 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/ast-methods.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/ast-methods.cpp
@@ -44,8 +44,7 @@ int main(int argc, char **argv) {
 // AST: |   |-ParmVarDecl {{.*}} 'char'
 // AST: |   `-ParmVarDecl {{.*}} 'int'
 
-// SYMBOL:      int main(int argc, char **argv);
-// SYMBOL-NEXT: struct Struct {
+// SYMBOL:      struct Struct {
 // SYMBOL-NEXT:     void simple_method();
 // SYMBOL-NEXT:     static void static_method();
 // SYMBOL-NEXT:     virtual void virtual_method();
@@ -53,3 +52,5 @@ int main(int argc, char **argv) {
 // SYMBOL-NEXT:     int overloaded_method(char);
 // SYMBOL-NEXT:     int overloaded_method(char, int, ...);
 // SYMBOL-NEXT: };
+// SYMBOL-NEXT: Struct s;
+// SYMBOL-NEXT: int main(int argc, char **argv);
\ No newline at end of file
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/global-ctor-dtor.cpp b/lldb/test/Shell/SymbolFile/NativePDB/global-ctor-dtor.cpp
index 15b4d330fabb0c..5e0fc4a8b78628 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/global-ctor-dtor.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/global-ctor-dtor.cpp
@@ -18,13 +18,14 @@ int main() {
   return 0;
 }
 
-// CHECK:      static void B::`dynamic initializer for 'glob'();
+// CHECK:      struct A {
+// CHECK-NEXT:     ~A();
+// CHECK-NEXT: };
+// CHECK-NEXT: A B::glob;
+// CHECK-NEXT: static void B::`dynamic initializer for 'glob'();
 // CHECK-NEXT: static void B::`dynamic atexit destructor for 'glob'();
 // CHECK-NEXT: int main();
 // CHECK-NEXT: static void _GLOBAL__sub_I_global_ctor_dtor.cpp();
-// CHECK-NEXT: struct A {
-// CHECK-NEXT:     ~A();
-// CHECK-NEXT: };
 // CHECK-NEXT: struct B {
 // CHECK-NEXT:     static A glob;
-// CHECK-NEXT: };
+// CHECK-NEXT: };
\ No newline at end of file
diff --git a/lldb/test/Shell/SymbolFile/PDB/ast-restore.test b/lldb/test/Shell/SymbolFile/PDB/ast-restore.test
index 2763f460702443..910d6dbfe23230 100644
--- a/lldb/test/Shell/SymbolFile/PDB/ast-restore.test
+++ b/lldb/test/Shell/SymbolFile/PDB/ast-restore.test
@@ -25,12 +25,7 @@ ENUM:         }
 ENUM:     }
 ENUM: }
 
-GLOBAL: Module: {{.*}}
-GLOBAL: namespace N0 {
-GLOBAL:     namespace N1 {
-GLOBAL:         N0::N1::(anonymous namespace)::Enum Global;
-GLOBAL:     }
-GLOBAL: }
+GLOBAL: N0::N1::(anonymous namespace)::Enum {{.*}}Global;
 
 BASE: Module: {{.*}}
 BASE: namespace N0 {
@@ -77,7 +72,7 @@ INNER: }
 
 TEMPLATE: Module: {{.*}}
 TEMPLATE: struct Template<N0::N1::Class> {
-TEMPLATE:     inline void TemplateFunc<1>();
+TEMPLATE:     void TemplateFunc<1>();
 TEMPLATE: };
 
 FOO: Module: {{.*}}



More information about the lldb-commits mailing list