Hi, When the inferior is built with GCC 4.7.2, the DWARF contains duplicate DW_AT_template_type_param DIEs for std::vector (and others). There is a reported GCC bug about it (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54410). Because of this, lldb parses the type "std::vector<bool, std::allocator<bool> >" as "std::vector<bool, std::allocator<bool, bool>, bool, std::allocator<bool, bool> >". Later, the FormatManager fails to match this type with the appropriate SyntheticChildrenFrontEnd for std::vector<bool>. The printable representation produced is then the incorrect: (lldb) frame variable vBool (std::vector<bool, std::allocator<bool, bool>, bool, std::allocator<bool, bool> >) vBool = size=0 {}
I've attached 3 patches (against r181819) for review: - An attempt at a workaround for the GCC bug - A change in the FormatManager to allow "std::vector<bool, std:allocator<bool> >" to be matched to the vector<bool> Synthetic. - The re-enabling of the test case Thanks, Yacine > http://llvm.org/bugs/show_bug.cgi?id=15301 > > Bug ID: 15301 > Summary: LLDB prints incorrect size of libstdc++ vector<bool> > containers (when inferior built with GCC on Linux) > Product: lldb > Version: unspecified > Hardware: PC > OS: Linux > Status: NEW > Severity: enhancement > Priority: P > Component: All Bugs > Assignee: lldb-dev at cs.uiuc.edu > Reporter: daniel.malea at intel.com > Classification: Unclassified > > In the TestDataFormatterStdVBool, instead of printing the correct size > (49) lldb prints -1 for the size of the std::vector<bool> container > (libstdc++). > > To reproduce, run: > > python dotest.py > functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool -C gcc > > -- > You are receiving this mail because: > You are the assignee for the bug. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > <http://lists.cs.uiuc.edu/pipermail/lldb-dev/attachments/20130219/8ff9c75c/attachment-0001.html>
>From 378aa04846a502dca2ad003ba13d14d51974f226 Mon Sep 17 00:00:00 2001 From: Yacine Belkadi <[email protected]> Date: Wed, 15 May 2013 21:52:00 +0200 Subject: [PATCH 1/3] SymbolFile/DWARF: Ignore duplicate template parameters DWARF produced by some versions of GCC (e.g. 4.7.2) may contain duplicate DW_TAG_template_value_param or DW_TAG_template_type_param entries. This results in incorrect parsing of types. For example: "std::vector<bool, std::allocator<bool, bool>, bool, std::allocator<bool, bool> >" instead of "std::vector<bool, std::allocator<bool> >". Fix that by ignoring duplicate template parameter DIE for DWARF produced by GCC. --- .../Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp | 9 ++++++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h | 3 ++ .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 33 ++++++++++++++------ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index ed615c4..ff4ce1b 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -942,6 +942,15 @@ DWARFCompileUnit::DW_AT_decl_file_attributes_are_invalid() return GetProducer() == eProducerLLVMGCC; } +bool +DWARFCompileUnit::MayContainDuplicateTemplateParameterDIE() +{ + // Some versions of GCC may produce duplicate DW_TAG_template_type_param or + // DW_TAG_template_value_param in the DWARF. + // GCC bug #54410 + return GetProducer() == eProducerGCC; +} + void DWARFCompileUnit::ParseProducerInfo () { diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 9fee0a2..459f78d 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -147,6 +147,9 @@ public: bool Supports_unnamed_objc_bitfields (); + bool + MayContainDuplicateTemplateParameterDIE(); + // void // AddGlobalDIEByIndex (uint32_t die_idx); // diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 9dd1dd4..5319b0a 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1280,12 +1280,11 @@ SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, if (clang_type) { + if (!(name && name[0])) + name = NULL; + + clang::TemplateArgument arg; bool is_signed = false; - if (name && name[0]) - template_param_infos.names.push_back(name); - else - template_param_infos.names.push_back(NULL); - clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type)); if (tag == DW_TAG_template_value_parameter && lldb_type != NULL && @@ -1293,14 +1292,30 @@ SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu, uval64_valid) { llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed); - template_param_infos.args.push_back (clang::TemplateArgument (*ast, - llvm::APSInt(apint), - clang_qual_type)); + arg = clang::TemplateArgument(*ast, llvm::APSInt(apint), clang_qual_type); } else { - template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type)); + arg = clang::TemplateArgument(clang_qual_type); } + + if (dwarf_cu->MayContainDuplicateTemplateParameterDIE() && name) + { + // Ignore already seen template parameters. + size_t num_template_params = template_param_infos.GetSize(); + for (size_t i = 0; i < num_template_params; ++i) + { + if (template_param_infos.names[i] && + (::strcmp(name, template_param_infos.names[i]) == 0) && + arg.structurallyEquals(template_param_infos.args[i])) + { + return false; + } + } + } + + template_param_infos.names.push_back(name); + template_param_infos.args.push_back(arg); } else { -- 1.7.10.4
>From a815d851c1dc15225f2efd86726aa590adf64023 Mon Sep 17 00:00:00 2001 From: Yacine Belkadi <[email protected]> Date: Wed, 15 May 2013 21:56:57 +0200 Subject: [PATCH 2/3] FormatManager: Match "std::vector<bool, std:allocator<bool> >" to the "vector<bool>" Synth The type "std::vector<bool, std:allocator<bool> >" wasn't matched to the appropriate SyntheticChildrenFrontEnd for std::vector<bool>. Add a regular expression to match both: "std::vector<bool, std:allocator<bool> >" (produced by GCC) and "std::vector<std:allocator<bool> >" (produced by Clang) Remove the vector<bool> specific Summary, as it's the same as the one for other vectors. --- source/DataFormatters/FormatManager.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/source/DataFormatters/FormatManager.cpp b/source/DataFormatters/FormatManager.cpp index a6a5416..6102003 100644 --- a/source/DataFormatters/FormatManager.cpp +++ b/source/DataFormatters/FormatManager.cpp @@ -554,7 +554,10 @@ FormatManager::LoadLibStdcppFormatters() SyntheticChildren::Flags stl_synth_flags; stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false); - + + gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<(bool,( )?)?std::allocator<bool> >$")), + SyntheticChildrenSP(new CXXSyntheticChildren(stl_synth_flags, "libstdc++ std::vector<bool> synthetic children", + lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEndCreator))); gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")), SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags, "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider"))); @@ -579,12 +582,6 @@ FormatManager::LoadLibStdcppFormatters() AddCXXSynthetic(gnu_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true); AddCXXSynthetic(gnu_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true); - - gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::vector<std::allocator<bool> >"), - TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); - - gnu_category_sp->GetSyntheticNavigator()->Add(ConstString("std::vector<std::allocator<bool> >"), - SyntheticChildrenSP(new CXXSyntheticChildren(stl_synth_flags,"libc++ std::vector<bool> synthetic children",lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEndCreator))); #endif } -- 1.7.10.4
>From 3d6c0438e657fadb5e3e95e2b1b3fab3366d457a Mon Sep 17 00:00:00 2001 From: Yacine Belkadi <[email protected]> Date: Wed, 15 May 2013 22:03:07 +0200 Subject: [PATCH 3/3] Tests: Re-enable TestDataFormatterStdVBool.py --- .../data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py b/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py index 8de8be7..e035418 100644 --- a/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py +++ b/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py @@ -31,7 +31,6 @@ class StdVBoolDataFormatterTestCase(TestBase): # Find the line number to break at. self.line = line_number('main.cpp', '// Set break point at this line.') - @expectedFailureGcc # PR-15301: lldb does not print the correct sizes of STL containers when building with GCC def data_formatter_commands(self): """Test that that file and class static variables display correctly.""" self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) -- 1.7.10.4
_______________________________________________ lldb-dev mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
