[Lldb-commits] [lldb] r205640 - Xcode 5 crashes if lldb stops at breakpoint if long c++ template lists are present.

Greg Clayton gclayton at apple.com
Fri Apr 4 11:15:19 PDT 2014


Author: gclayton
Date: Fri Apr  4 13:15:18 2014
New Revision: 205640

URL: http://llvm.org/viewvc/llvm-project?rev=205640&view=rev
Log:
Xcode 5 crashes if lldb stops at breakpoint if long c++ template lists are present. 

This fix reduces the stack size of SymbolFileDWARF::ParseType(). It seems that clang is not very good at sharing locations on the stack with local variables in large functions that have many blocks and each variable gets unique locations. The reduction in size was done by:
1 - removing some large locals that were default constructed by not used
2 - Placing some larger local variables into std::unique_ptr<> to make them on the heap
3 - removing local variables there were large and being populated but not being used
4 - reducing the size of some typedefs to llvm::SmallVector<T, N> so that N wasn’t excessively large


<rdar://problem/16431645>

Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=205640&r1=205639&r2=205640&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Fri Apr  4 13:15:18 2014
@@ -258,8 +258,8 @@ public:
             return 0;
         }
 
-        llvm::SmallVector<const char *, 8> names;
-        llvm::SmallVector<clang::TemplateArgument, 8> args;        
+        llvm::SmallVector<const char *, 2> names;
+        llvm::SmallVector<clang::TemplateArgument, 2> args;
     };
 
     clang::FunctionTemplateDecl *

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h?rev=205640&r1=205639&r2=205640&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h Fri Apr  4 13:15:18 2014
@@ -86,7 +86,7 @@ public:
             dw_form_t form;
         };
 
-        typedef llvm::SmallVector<Info, 32> collection;
+        typedef llvm::SmallVector<Info, 8> collection;
         collection m_infos;
     };
 

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=205640&r1=205639&r2=205640&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Apr  4 13:15:18 2014
@@ -4185,8 +4185,8 @@ SymbolFileDWARF::ParseChildParameters (c
                                        TypeList* type_list,
                                        std::vector<ClangASTType>& function_param_types,
                                        std::vector<clang::ParmVarDecl*>& function_param_decls,
-                                       unsigned &type_quals,
-                                       ClangASTContext::TemplateParameterInfos &template_param_infos)
+                                       unsigned &type_quals) // ,
+                                       // ClangASTContext::TemplateParameterInfos &template_param_infos))
 {
     if (parent_die == NULL)
         return 0;
@@ -4339,7 +4339,11 @@ SymbolFileDWARF::ParseChildParameters (c
 
         case DW_TAG_template_type_parameter:
         case DW_TAG_template_value_parameter:
-            ParseTemplateDIE (dwarf_cu, die,template_param_infos);
+            // The one caller of this was never using the template_param_infos,
+            // and the local variable was taking up a large amount of stack space
+            // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
+            // the template params back, we can add them back.
+            // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
             break;
 
         default:
@@ -5370,7 +5374,7 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
                                              const DWARFDebugInfoEntry *src_class_die,
                                              DWARFCompileUnit* dst_cu,
                                              const DWARFDebugInfoEntry *dst_class_die,
-                                             llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures)
+                                             DWARFDIECollection &failures)
 {
     if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
         return false;
@@ -5595,7 +5599,7 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
                     if (log)
                         log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());
 
-                    failures.push_back(dst_die);
+                    failures.Append(dst_die);
                 }
             }
         }
@@ -5662,11 +5666,11 @@ SymbolFileDWARF::CopyUniqueClassMethodTy
             if (log)
                 log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
             
-            failures.push_back(dst_die);
+            failures.Append(dst_die);
         }
     }
 
-    return (failures.size() != 0);
+    return (failures.Size() != 0);
 }
 
 TypeSP
@@ -5733,7 +5737,8 @@ SymbolFileDWARF::ParseType (const Symbol
 
             Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
             ClangASTType clang_type;
-
+            DWARFFormValue form_value;
+            
             dw_attr_t attr;
 
             switch (tag)
@@ -5761,7 +5766,6 @@ SymbolFileDWARF::ParseType (const Symbol
                         for (i=0; i<num_attributes; ++i)
                         {
                             attr = attributes.AttributeAtIndex(i);
-                            DWARFFormValue form_value;
                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                             {
                                 switch (attr)
@@ -5946,7 +5950,6 @@ SymbolFileDWARF::ParseType (const Symbol
                         for (i=0; i<num_attributes; ++i)
                         {
                             attr = attributes.AttributeAtIndex(i);
-                            DWARFFormValue form_value;
                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                             {
                                 switch (attr)
@@ -6010,8 +6013,11 @@ SymbolFileDWARF::ParseType (const Symbol
                             }
                         }
                     }
-
-                    UniqueDWARFASTType unique_ast_entry;
+                    
+                    // UniqueDWARFASTType is large, so don't create a local variables on the
+                    // stack, put it on the heap. This function is often called recursively
+                    // and clang isn't good and sharing the stack space for variables in different blocks.
+                    std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());
 
                     // Only try and unique the type if it has a name. 
                     if (type_name_const_str &&
@@ -6021,14 +6027,14 @@ SymbolFileDWARF::ParseType (const Symbol
                                                          die,
                                                          decl,
                                                          byte_size_valid ? byte_size : -1,
-                                                         unique_ast_entry))
+                                                         *unique_ast_entry_ap))
                     {
                         // We have already parsed this type or from another 
                         // compile unit. GCC loves to use the "one definition
                         // rule" which can result in multiple definitions
                         // of the same class over and over in each compile
                         // unit.
-                        type_sp = unique_ast_entry.m_type_sp;
+                        type_sp = unique_ast_entry_ap->m_type_sp;
                         if (type_sp)
                         {
                             m_die_to_type[die] = type_sp.get();
@@ -6245,14 +6251,14 @@ SymbolFileDWARF::ParseType (const Symbol
                     // Add our type to the unique type map so we don't
                     // end up creating many copies of the same type over
                     // and over in the ASTContext for our module
-                    unique_ast_entry.m_type_sp = type_sp;
-                    unique_ast_entry.m_symfile = this;
-                    unique_ast_entry.m_cu = dwarf_cu;
-                    unique_ast_entry.m_die = die;
-                    unique_ast_entry.m_declaration = decl;
-                    unique_ast_entry.m_byte_size = byte_size;
+                    unique_ast_entry_ap->m_type_sp = type_sp;
+                    unique_ast_entry_ap->m_symfile = this;
+                    unique_ast_entry_ap->m_cu = dwarf_cu;
+                    unique_ast_entry_ap->m_die = die;
+                    unique_ast_entry_ap->m_declaration = decl;
+                    unique_ast_entry_ap->m_byte_size = byte_size;
                     GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, 
-                                                       unique_ast_entry);
+                                                       *unique_ast_entry_ap);
 
                     if (is_forward_declaration && die->HasChildren())
                     {
@@ -6300,14 +6306,7 @@ SymbolFileDWARF::ParseType (const Symbol
                                 clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();
 
                                 if (record_decl)
-                                {
-                                    LayoutInfo layout_info;
-
-                                    layout_info.alignment = 0;
-                                    layout_info.bit_size = 0;
-
-                                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
-                                }
+                                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
                             }
                         }
                         else if (clang_type_was_created)
@@ -6353,7 +6352,6 @@ SymbolFileDWARF::ParseType (const Symbol
                         for (i=0; i<num_attributes; ++i)
                         {
                             attr = attributes.AttributeAtIndex(i);
-                            DWARFFormValue form_value;
                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                             {
                                 switch (attr)
@@ -6469,7 +6467,6 @@ SymbolFileDWARF::ParseType (const Symbol
                         for (i=0; i<num_attributes; ++i)
                         {
                             attr = attributes.AttributeAtIndex(i);
-                            DWARFFormValue form_value;
                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                             {
                                 switch (attr)
@@ -6583,8 +6580,7 @@ SymbolFileDWARF::ParseType (const Symbol
                     // if we find a "this" paramters as the first parameter
                     if (is_cxx_method)
                         is_static = true;
-                    ClangASTContext::TemplateParameterInfos template_param_infos;
-
+                    
                     if (die->HasChildren())
                     {
                         bool skip_artificial = true;
@@ -6598,8 +6594,7 @@ SymbolFileDWARF::ParseType (const Symbol
                                               type_list,
                                               function_param_types,
                                               function_param_decls,
-                                              type_quals,
-                                              template_param_infos);
+                                              type_quals);
                     }
 
                     // clang_type will get the function prototype clang type after this call
@@ -6619,12 +6614,10 @@ SymbolFileDWARF::ParseType (const Symbol
                             ObjCLanguageRuntime::MethodName objc_method (type_name_cstr, true);
                             if (objc_method.IsValid(true))
                             {
-                                SymbolContext empty_sc;
                                 ClangASTType class_opaque_type;
                                 ConstString class_name(objc_method.GetClassName());
                                 if (class_name)
                                 {
-                                    TypeList types;
                                     TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false));
 
                                     if (complete_objc_class_type_sp)
@@ -6691,7 +6684,7 @@ SymbolFileDWARF::ParseType (const Symbol
                                         }
                                         if (class_type_die)
                                         {
-                                            llvm::SmallVector<const DWARFDebugInfoEntry *, 0> failures;
+                                            DWARFDIECollection failures;
 
                                             CopyUniqueClassMethodTypes (class_symfile,
                                                                         class_type,
@@ -6940,7 +6933,6 @@ SymbolFileDWARF::ParseType (const Symbol
                         for (i=0; i<num_attributes; ++i)
                         {
                             attr = attributes.AttributeAtIndex(i);
-                            DWARFFormValue form_value;
                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                             {
                                 switch (attr)
@@ -7028,7 +7020,6 @@ SymbolFileDWARF::ParseType (const Symbol
                         for (i=0; i<num_attributes; ++i)
                         {
                             attr = attributes.AttributeAtIndex(i);
-                            DWARFFormValue form_value;
                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                             {
                                 switch (attr)

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=205640&r1=205639&r2=205640&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Fri Apr  4 13:15:18 2014
@@ -368,9 +368,10 @@ protected:
                                 lldb_private::TypeList* type_list,
                                 std::vector<lldb_private::ClangASTType>& function_args,
                                 std::vector<clang::ParmVarDecl*>& function_param_decls,
-                                unsigned &type_quals,
-                                lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
-
+                                unsigned &type_quals);
+                                // lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos); // not currently needed
+    
+    
     size_t                  ParseChildEnumerators(
                                 const lldb_private::SymbolContext& sc,
                                 lldb_private::ClangASTType &clang_type,
@@ -546,7 +547,7 @@ protected:
                                 const DWARFDebugInfoEntry *src_class_die,
                                 DWARFCompileUnit* dst_cu,
                                 const DWARFDebugInfoEntry *dst_class_die,
-                                llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures);
+                                DWARFDIECollection &failures);
 
     bool
     FixupAddress (lldb_private::Address &addr);





More information about the lldb-commits mailing list