[Lldb-commits] [lldb] r197108 - LLDB can crash if given DWARF debug info for a class that has a base class which isn't a complete definition.

Greg Clayton gclayton at apple.com
Wed Dec 11 17:54:04 PST 2013


Author: gclayton
Date: Wed Dec 11 19:54:04 2013
New Revision: 197108

URL: http://llvm.org/viewvc/llvm-project?rev=197108&view=rev
Log:
LLDB can crash if given DWARF debug info for a class that has a base class which isn't a complete definition. 

<rdar://problem/15594781>

We need to not crash at any cost. We currently detect if any base classes are forward declarations, emit an error string that directs the use to file a compiler bug, and continues by completing the class with no contents. This avoids a clang crash that would usually follow when we call setBase().


Modified:
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

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=197108&r1=197107&r2=197108&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Dec 11 19:54:04 2013
@@ -2556,6 +2556,37 @@ SymbolFileDWARF::ResolveClangOpaqueTypeD
                     
                     if (!base_classes.empty())
                     {
+                        // Make sure all base classes refer to complete types and not
+                        // forward declarations. If we don't do this, clang will crash
+                        // with an assertion in the call to clang_type.SetBaseClassesForClassType()
+                        bool base_class_error = false;
+                        for (auto &base_class : base_classes)
+                        {
+                            clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo();
+                            if (type_source_info)
+                            {
+                                ClangASTType base_class_type (GetClangASTContext().getASTContext(), type_source_info->getType());
+                                if (base_class_type.GetCompleteType() == false)
+                                {
+                                    if (!base_class_error)
+                                    {
+                                        GetObjectFile()->GetModule()->ReportError ("DWARF DIE at 0x%8.8x for class '%s' has a base class '%s' that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
+                                                                                   die->GetOffset(),
+                                                                                   die->GetName(this, dwarf_cu),
+                                                                                   base_class_type.GetTypeName().GetCString(),
+                                                                                   sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
+                                    }
+                                    // We have no choice other than to pretend that the base class
+                                    // is complete. If we don't do this, clang will crash when we
+                                    // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
+                                    // below. Since we provide layout assistance, all ivars in this
+                                    // class and other classe will be fine, this is the best we can do
+                                    // short of crashing.
+                                    base_class_type.StartTagDeclarationDefinition ();
+                                    base_class_type.CompleteTagDeclarationDefinition ();
+                                }
+                            }
+                        }
                         clang_type.SetBaseClassesForClassType (&base_classes.front(),
                                                                base_classes.size());
                         





More information about the lldb-commits mailing list