[Lldb-commits] [lldb] r250965 - Fix libstdc++ data formatters on Ubuntu 15.10 x86_64

Todd Fiala via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 21 17:23:39 PDT 2015


Author: tfiala
Date: Wed Oct 21 19:23:38 2015
New Revision: 250965

URL: http://llvm.org/viewvc/llvm-project?rev=250965&view=rev
Log:
Fix libstdc++ data formatters on Ubuntu 15.10 x86_64

See http://reviews.llvm.org/D13964 for details.

Modified:
    lldb/trunk/examples/synthetic/gnu_libstdcpp.py
    lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
    lldb/trunk/test/make/Makefile.rules

Modified: lldb/trunk/examples/synthetic/gnu_libstdcpp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/gnu_libstdcpp.py?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/gnu_libstdcpp.py (original)
+++ lldb/trunk/examples/synthetic/gnu_libstdcpp.py Wed Oct 21 19:23:38 2015
@@ -13,7 +13,7 @@ class StdListSynthProvider:
 		logger = lldb.formatters.Logger.Logger()
 		self.valobj = valobj
 		self.count = None
-		logger >> "Providing synthetic children for a map named " + str(valobj.GetName())
+		logger >> "Providing synthetic children for a list named " + str(valobj.GetName())
 
 	def next_node(self,node):
 		logger = lldb.formatters.Logger.Logger()
@@ -21,11 +21,20 @@ class StdListSynthProvider:
 
 	def is_valid(self,node):
 		logger = lldb.formatters.Logger.Logger()
-		return self.value(self.next_node(node)) != self.node_address
+		valid = self.value(self.next_node(node)) != self.node_address
+                if valid:
+                        logger >> "%s is valid" % str(self.valobj.GetName())
+                else:
+                        logger >> "synthetic value is not valid"
+                return valid
 
 	def value(self,node):
 		logger = lldb.formatters.Logger.Logger()
-		return node.GetValueAsUnsigned()
+                value = node.GetValueAsUnsigned()
+                logger >> "synthetic value for {}: {}".format(
+                        str(self.valobj.GetName()),
+                        value)
+                return value
 
 	# Floyd's cycle-finding algorithm
 	# try to detect if this list has a loop
@@ -49,7 +58,12 @@ class StdListSynthProvider:
 
 	def num_children(self):
 		logger = lldb.formatters.Logger.Logger()
-		if self.count == None:
+		if self.count is None:
+                        # libstdc++ 6.0.21 added dedicated count field.
+                        count_child = self.node.GetChildMemberWithName('_M_data')
+                        if count_child and count_child.IsValid():
+                                self.count = count_child.GetValueAsUnsigned(0)
+                if self.count is None:
 			self.count = self.num_children_impl()
 		return self.count
 
@@ -117,10 +131,10 @@ class StdListSynthProvider:
 		self.count = None
 		try:
 			impl = self.valobj.GetChildMemberWithName('_M_impl')
-			node = impl.GetChildMemberWithName('_M_node')
+			self.node = impl.GetChildMemberWithName('_M_node')
 			self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
-			self.next = node.GetChildMemberWithName('_M_next')
-			self.prev = node.GetChildMemberWithName('_M_prev')
+			self.next = self.node.GetChildMemberWithName('_M_next')
+			self.prev = self.node.GetChildMemberWithName('_M_prev')
 			self.data_type = self.extract_type()
 			self.data_size = self.data_type.GetByteSize()
 		except:

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp Wed Oct 21 19:23:38 2015
@@ -545,7 +545,14 @@ LoadLibStdcppFormatters(lldb::TypeCatego
     
     lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(stl_summary_flags,
                                                                           "${var._M_dataplus._M_p}"));
-    
+
+    lldb::TypeSummaryImplSP cxx11_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags,
+                                                                                 LibStdcppStringSummaryProvider,
+                                                                                 "libstdc++ c++11 std::string summary provider"));
+    lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags,
+                                                                                 LibStdcppWStringSummaryProvider,
+                                                                                 "libstdc++ c++11 std::wstring summary provider"));
+
     cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
                                                       std_string_summary_sp);
     cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char>"),
@@ -554,7 +561,12 @@ LoadLibStdcppFormatters(lldb::TypeCatego
                                                       std_string_summary_sp);
     cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
                                                       std_string_summary_sp);
-    
+
+    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::string"),
+                                                      cxx11_string_summary_sp);
+    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
+                                                      cxx11_string_summary_sp);
+
     // making sure we force-pick the summary for printing wstring (_M_p is a wchar_t*)
     lldb::TypeSummaryImplSP std_wstring_summary_sp(new StringSummaryFormat(stl_summary_flags,
                                                                            "${var._M_dataplus._M_p%S}"));
@@ -567,8 +579,12 @@ LoadLibStdcppFormatters(lldb::TypeCatego
                                                       std_wstring_summary_sp);
     cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
                                                       std_wstring_summary_sp);
-    
-    
+
+    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::wstring"),
+                                                      cxx11_wstring_summary_sp);
+    cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
+                                                      cxx11_wstring_summary_sp);
+
 #ifndef LLDB_DISABLE_PYTHON
     
     SyntheticChildren::Flags stl_synth_flags;
@@ -580,9 +596,16 @@ LoadLibStdcppFormatters(lldb::TypeCatego
     cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
                                                             SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                               "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
-    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
+    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
                                                             SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                               "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
+#if 0
+    // With only this, I get std::list showing the content, all children on the same line.
+    // With this and the section below, I see one child element per line.
+    cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new RegularExpression("^std::__cxx11::_List_base<.+>(( )?&)?$")),
+                                                            SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+                                                                                                              "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
+#endif
     
     stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
     cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
@@ -591,10 +614,16 @@ LoadLibStdcppFormatters(lldb::TypeCatego
     cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
                                                            TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
                                                                                                      "size=${svar%#}")));
-    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
+    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
                                                            TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
                                                                                                      "size=${svar%#}")));
-    
+#if 0
+    // With this, I get std::list showing one child per line.  Requires the change above to get anything, though.
+    cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression("^std::__cxx11::_List_base<.+>(( )?&)?$")),
+                                                           TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+                                                                                                     "size=${svar%#}")));
+#endif
+
     AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
     
     AddCXXSynthetic(cpp_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp Wed Oct 21 19:23:38 2015
@@ -14,6 +14,7 @@
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/StringPrinter.h"
 #include "lldb/DataFormatters/VectorIterator.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
@@ -256,3 +257,117 @@ lldb_private::formatters::VectorIterator
 lldb_private::formatters::VectorIteratorSyntheticFrontEnd::~VectorIteratorSyntheticFrontEnd ()
 {
 }
+
+bool
+lldb_private::formatters::LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+    const bool scalar_is_load_addr = true;
+    AddressType addr_type;
+    lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
+    if (addr_of_string != LLDB_INVALID_ADDRESS)
+    {
+        switch (addr_type)
+        {
+            case eAddressTypeLoad:
+            {
+                ProcessSP process_sp(valobj.GetProcessSP());
+                if (!process_sp)
+                    return false;
+
+                StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+                Error error;
+                lldb::addr_t addr_of_data = process_sp->ReadPointerFromMemory(addr_of_string, error);
+                if (error.Fail() || addr_of_data == 0 || addr_of_data == LLDB_INVALID_ADDRESS)
+                    return false;
+                options.SetLocation(addr_of_data);
+                options.SetProcessSP(process_sp);
+                options.SetStream(&stream);
+                options.SetNeedsZeroTermination(false);
+                options.SetBinaryZeroIsTerminator(true);
+                lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(addr_of_string + process_sp->GetAddressByteSize(), error);
+                if (error.Fail())
+                    return false;
+                options.SetSourceSize(size_of_data);
+
+                if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options))
+                {
+                    stream.Printf("Summary Unavailable");
+                    return true;
+                }
+                else
+                    return true;
+            }
+                break;
+            case eAddressTypeHost:
+                break;
+            case eAddressTypeInvalid:
+            case eAddressTypeFile:
+                break;
+        }
+    }
+    return false;
+}
+
+bool
+lldb_private::formatters::LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+    const bool scalar_is_load_addr = true;
+    AddressType addr_type;
+    lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
+    if (addr_of_string != LLDB_INVALID_ADDRESS)
+    {
+        switch (addr_type)
+        {
+            case eAddressTypeLoad:
+            {
+                ProcessSP process_sp(valobj.GetProcessSP());
+                if (!process_sp)
+                    return false;
+
+                CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
+
+                if (!wchar_compiler_type)
+                    return false;
+
+                const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
+
+                StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+                Error error;
+                lldb::addr_t addr_of_data = process_sp->ReadPointerFromMemory(addr_of_string, error);
+                if (error.Fail() || addr_of_data == 0 || addr_of_data == LLDB_INVALID_ADDRESS)
+                    return false;
+                options.SetLocation(addr_of_data);
+                options.SetProcessSP(process_sp);
+                options.SetStream(&stream);
+                options.SetNeedsZeroTermination(false);
+                options.SetBinaryZeroIsTerminator(false);
+                lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(addr_of_string + process_sp->GetAddressByteSize(), error);
+                if (error.Fail())
+                    return false;
+                options.SetSourceSize(size_of_data);
+                options.SetPrefixToken("L");
+
+                switch (wchar_size)
+                {
+                    case 8:
+                        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
+                    case 16:
+                        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+                    case 32:
+                        return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
+                    default:
+                        stream.Printf("size for wchar_t is not valid");
+                        return true;
+                }
+                return true;
+            }
+                break;
+            case eAddressTypeHost:
+                break;
+            case eAddressTypeInvalid:
+            case eAddressTypeFile:
+                break;
+        }
+    }
+    return false;
+}

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h Wed Oct 21 19:23:38 2015
@@ -18,6 +18,12 @@
 namespace lldb_private {
     namespace formatters
     {
+        bool
+        LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libcstdc++ c++11 std::string
+
+        bool
+        LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options); // libcstdc++ c++11 std::wstring
+
         SyntheticChildrenFrontEnd* LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
         
         SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp Wed Oct 21 19:23:38 2015
@@ -15,6 +15,7 @@ typedef std::list<int> int_list;
 
 int main()
 {
+#ifdef LLDB_USING_LIBCPP
     int_list *numbers_list = new int_list{1,2,3,4,5,6,7,8,9,10};
 
     auto *third_elem = numbers_list->__end_.__next_->__next_->__next_; // Set break point at this line.
@@ -22,6 +23,7 @@ int main()
     auto *fifth_elem = third_elem->__next_->__next_;
     assert(fifth_elem->__value_ == 5);
     fifth_elem->__next_ = third_elem;
+#endif
 
     // Any attempt to free the list will probably crash the program. Let's just leak it.
     return 0; // Set second break point at this line.

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py Wed Oct 21 19:23:38 2015
@@ -47,21 +47,21 @@ class StdStringDataFormatterTestCase(Tes
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
-        self.expect("frame variable",
-                    substrs = ['(std::wstring) s = L"hello world! מזל טוב!"',
-                    '(std::wstring) S = L"!!!!"',
-                    '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
-                    '(std::string) q = "hello world"',
-                    '(std::string) Q = "quite a long std::strin with lots of info inside it"'])
+        var_s = self.frame().FindVariable('s')
+        var_S = self.frame().FindVariable('S')
+        var_mazeltov = self.frame().FindVariable('mazeltov')
+        var_q = self.frame().FindVariable('q')
+        var_Q = self.frame().FindVariable('Q')
 
-        self.runCmd("n")
+        self.assertTrue(var_s.GetSummary() == 'L"hello world! מזל טוב!"', "s summary wrong")
+        self.assertTrue(var_S.GetSummary() == 'L"!!!!"', "S summary wrong")
+        self.assertTrue(var_mazeltov.GetSummary() == 'L"מזל טוב"', "mazeltov summary wrong")
+        self.assertTrue(var_q.GetSummary() == '"hello world"', "q summary wrong")
+        self.assertTrue(var_Q.GetSummary() == '"quite a long std::strin with lots of info inside it"', "Q summary wrong")
 
-        self.expect("frame variable",
-                    substrs = ['(std::wstring) s = L"hello world! מזל טוב!"',
-                    '(std::wstring) S = L"!!!!!"',
-                    '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
-                    '(std::string) q = "hello world"',
-                    '(std::string) Q = "quite a long std::strin with lots of info inside it"'])
+        self.runCmd("next")
+
+        self.assertTrue(var_S.GetSummary() == 'L"!!!!!"', "new S summary wrong")
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/make/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/make/Makefile.rules?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/test/make/Makefile.rules (original)
+++ lldb/trunk/test/make/Makefile.rules Wed Oct 21 19:23:38 2015
@@ -296,12 +296,12 @@ ifeq (1,$(USE_LIBCPP))
 		ifeq "$(OS)" "Linux"
 			# This is the default install location on Ubuntu 14.04
 			ifneq ($(wildcard /usr/include/c++/v1/.),)
-				CXXFLAGS += -stdlib=libc++
+				CXXFLAGS += -stdlib=libc++ -DLLDB_USING_LIBCPP
 				LDFLAGS += -stdlib=libc++
 				CXXFLAGS += -I/usr/include/c++/v1
 			endif
 		else
-			CXXFLAGS += -stdlib=libc++
+			CXXFLAGS += -stdlib=libc++ -DLLDB_USING_LIBCPP
 			LDFLAGS += -stdlib=libc++
 		endif
 	endif




More information about the lldb-commits mailing list