[Lldb-commits] [lldb] r327750 - [DWARFASTParserClang] Complete external record types before using them as a decl context.

Frederic Riss via lldb-commits lldb-commits at lists.llvm.org
Fri Mar 16 15:12:22 PDT 2018


Author: friss
Date: Fri Mar 16 15:12:22 2018
New Revision: 327750

URL: http://llvm.org/viewvc/llvm-project?rev=327750&view=rev
Log:
[DWARFASTParserClang] Complete external record types before using them as a decl context.

Summary:
When in a gmodules-like debugging scenario, you can have a parent decl context
that gets imported from an external AST. When this happens, we must be careful
to complete this type before adding children to it, otherwise it sometimes
results in a crash.

Reviewers: clayborg, jingham

Subscribers: aprantl, JDevlieghere, lldb-commits

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

Modified:
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py?rev=327750&r1=327749&r2=327750&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py Fri Mar 16 15:12:22 2018
@@ -69,3 +69,26 @@ class TestWithGmodulesDebugInfo(TestBase
             42,
             memberValue.GetValueAsSigned(),
             "Member value incorrect")
+
+        testValue = frame.EvaluateExpression("bar")
+        self.assertTrue(
+            testValue.GetError().Success(),
+            "Test expression value invalid: %s" %
+            (testValue.GetError().GetCString()))
+        self.assertTrue(
+            testValue.GetTypeName() == "Foo::Bar",
+            "Test expression type incorrect")
+
+        memberValue = testValue.GetChildMemberWithName("i")
+        self.assertTrue(
+            memberValue.GetError().Success(),
+            "Member value missing or invalid: %s" %
+            (testValue.GetError().GetCString()))
+        self.assertTrue(
+            memberValue.GetTypeName() == "int",
+            "Member type incorrect")
+        self.assertEqual(
+            123,
+            memberValue.GetValueAsSigned(),
+            "Member value incorrect")
+

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp?rev=327750&r1=327749&r2=327750&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp Fri Mar 16 15:12:22 2018
@@ -1,5 +1,8 @@
+class Foo::Bar { int i = 123; };
+
 int main(int argc, const char * argv[])
 {
     IntContainer test(42);
+    Foo::Bar bar;
     return 0; // break here
 }

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h?rev=327750&r1=327749&r2=327750&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h Fri Mar 16 15:12:22 2018
@@ -10,3 +10,8 @@ class GenericContainer {
 };
 
 typedef GenericContainer<int> IntContainer;
+
+struct Foo {
+  class Bar;
+  Bar *bar;
+};

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=327750&r1=327749&r2=327750&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Fri Mar 16 15:12:22 2018
@@ -205,6 +205,33 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   return type_sp;
 }
 
+static void CompleteExternalTagDeclType(ClangASTImporter &ast_importer,
+                                        clang::DeclContext *decl_ctx,
+                                        DWARFDIE die,
+                                        const char *type_name_cstr) {
+  auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
+  if (!tag_decl_ctx)
+    return;
+
+  // If this type was not imported from an external AST, there's
+  // nothing to do.
+  CompilerType type = ClangASTContext::GetTypeForDecl(tag_decl_ctx);
+  if (!type || !ast_importer.CanImport(type))
+    return;
+
+  auto qual_type = ClangUtil::GetQualType(type);
+  if (!ast_importer.RequireCompleteType(qual_type)) {
+    die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
+        "Unable to complete the Decl context for DIE '%s' at offset "
+        "0x%8.8x.\nPlease file a bug report.",
+        type_name_cstr ?: "", die.GetOffset());
+    // We need to make the type look complete otherwise, we
+    // might crash in Clang when adding children.
+    if (ClangASTContext::StartTagDeclarationDefinition(type))
+      ClangASTContext::CompleteTagDeclarationDefinition(type);
+  }
+}
+
 TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
                                                const DWARFDIE &die, Log *log,
                                                bool *type_is_new_ptr) {
@@ -795,6 +822,16 @@ TypeSP DWARFASTParserClang::ParseTypeFro
         if (!clang_type) {
           clang::DeclContext *decl_ctx =
               GetClangDeclContextContainingDIE(die, nullptr);
+
+          // If your decl context is a record that was imported from
+          // another AST context (in the gmodules case), we need to
+          // make sure the type backing the Decl is complete before
+          // adding children to it. This is not an issue in the
+          // non-gmodules case because the debug info will always contain
+          // a full definition of parent types in that case.
+          CompleteExternalTagDeclType(GetClangASTImporter(), decl_ctx, die,
+                                      type_name_cstr);
+
           if (accessibility == eAccessNone && decl_ctx) {
             // Check the decl context that contains this class/struct/union.
             // If it is a class we must give it an accessibility.




More information about the lldb-commits mailing list