From e7dd3972094c2f2fb42dc9d4d5344e54a431e2ce Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 25 Oct 2016 13:24:53 +0000 Subject: [PATCH] Revert "Improve the libstdc++ smart pointer formatters" This reverts commit r284828, as it causes an infinite loop in TestPrintStackTraces (funnily enough, only when logging is enabled). llvm-svn: 285068 --- .../libstdcpp/smart_ptr/Makefile | 9 +- .../smart_ptr/TestDataFormatterStdSmartPtr.py | 55 +----- .../Plugins/Language/CPlusPlus/CMakeLists.txt | 1 - .../Plugins/Language/CPlusPlus/LibStdcpp.cpp | 92 ++++++++++ .../Language/CPlusPlus/LibStdcppSmartPointer.cpp | 200 --------------------- 5 files changed, 108 insertions(+), 249 deletions(-) delete mode 100644 lldb/source/Plugins/Language/CPlusPlus/LibStdcppSmartPointer.cpp diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile index beb2fd5..88cb026 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile +++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/Makefile @@ -2,7 +2,14 @@ LEVEL = ../../../../../make CXX_SOURCES := main.cpp +CXXFLAGS := -O0 USE_LIBSTDCPP := 1 -CFLAGS_EXTRAS += $(NO_LIMIT_DEBUG_INFO_FLAGS) + +# clang-3.5+ outputs FullDebugInfo by default for Darwin/FreeBSD +# targets. Other targets do not, which causes this test to fail. +# This flag enables FullDebugInfo for all targets. +ifneq (,$(findstring clang,$(CC))) + CFLAGS_EXTRAS += -fno-limit-debug-info +endif include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py index 978c2ac..8d940c2 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/smart_ptr/TestDataFormatterStdSmartPtr.py @@ -31,58 +31,19 @@ class StdSmartPtrDataFormatterTestCase(TestBase): substrs=['stopped', 'stop reason = breakpoint']) self.expect("frame variable nsp", substrs=['nsp = nullptr']) - self.expect("frame variable isp", substrs=['isp = 123', 'strong=1', 'weak=1']) - self.expect("frame variable ssp", substrs=['ssp = "foobar"', 'strong=1', 'weak=1']) - self.expect("frame variable nwp", substrs=['nwp = nullptr']) - self.expect("frame variable iwp", substrs=['iwp = 123', 'strong=1', 'weak=1']) - self.expect("frame variable swp", substrs=['swp = "foobar"', 'strong=1', 'weak=1']) - - frame = self.frame() - self.assertTrue(frame.IsValid()) - - self.assertEqual(0, frame.GetValueForVariablePath("nsp.pointer").GetValueAsUnsigned()) - self.assertEqual(0, frame.GetValueForVariablePath("nwp.pointer").GetValueAsUnsigned()) - - self.assertNotEqual(0, frame.GetValueForVariablePath("isp.pointer").GetValueAsUnsigned()) - self.assertEqual(123, frame.GetValueForVariablePath("isp.object").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("isp.count").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("isp.weak_count").GetValueAsUnsigned()) - self.assertFalse(frame.GetValueForVariablePath("isp.foobar").IsValid()) + self.expect("frame variable isp", substrs=['isp = 123']) + self.expect("frame variable ssp", substrs=['ssp = "foobar"']) - self.assertNotEqual(0, frame.GetValueForVariablePath("ssp.pointer").GetValueAsUnsigned()) - self.assertEqual('"foobar"', frame.GetValueForVariablePath("ssp.object").GetSummary()) - self.assertEqual(1, frame.GetValueForVariablePath("ssp.count").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("ssp.weak_count").GetValueAsUnsigned()) - self.assertFalse(frame.GetValueForVariablePath("ssp.foobar").IsValid()) - - self.assertNotEqual(0, frame.GetValueForVariablePath("iwp.pointer").GetValueAsUnsigned()) - self.assertEqual(123, frame.GetValueForVariablePath("iwp.object").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("iwp.count").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("iwp.weak_count").GetValueAsUnsigned()) - self.assertFalse(frame.GetValueForVariablePath("iwp.foobar").IsValid()) - - self.assertNotEqual(0, frame.GetValueForVariablePath("swp.pointer").GetValueAsUnsigned()) - self.assertEqual('"foobar"', frame.GetValueForVariablePath("swp.object").GetSummary()) - self.assertEqual(1, frame.GetValueForVariablePath("swp.count").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("swp.weak_count").GetValueAsUnsigned()) - self.assertFalse(frame.GetValueForVariablePath("swp.foobar").IsValid()) + self.expect("frame variable nwp", substrs=['nwp = nullptr']) + self.expect("frame variable iwp", substrs=['iwp = 123']) + self.expect("frame variable swp", substrs=['swp = "foobar"']) self.runCmd("continue") - frame = self.frame() - self.assertTrue(frame.IsValid()) - self.expect("frame variable nsp", substrs=['nsp = nullptr']) self.expect("frame variable isp", substrs=['isp = nullptr']) self.expect("frame variable ssp", substrs=['ssp = nullptr']) - self.expect("frame variable nwp", substrs=['nwp = nullptr']) - self.expect("frame variable iwp", substrs=['iwp = nullptr', 'strong=0', 'weak=1']) - self.expect("frame variable swp", substrs=['swp = nullptr', 'strong=0', 'weak=1']) - self.assertFalse(frame.GetValueForVariablePath("iwp.object").IsValid()) - self.assertEqual(0, frame.GetValueForVariablePath("iwp.count").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("iwp.weak_count").GetValueAsUnsigned()) - - self.assertFalse(frame.GetValueForVariablePath("swp.object").IsValid()) - self.assertEqual(0, frame.GetValueForVariablePath("swp.count").GetValueAsUnsigned()) - self.assertEqual(1, frame.GetValueForVariablePath("swp.weak_count").GetValueAsUnsigned()) + self.expect("frame variable nwp", substrs=['nwp = nullptr']) + self.expect("frame variable iwp", substrs=['iwp = nullptr']) + self.expect("frame variable swp", substrs=['swp = nullptr']) diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt index a72aee7..5e105aa 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -10,7 +10,6 @@ add_lldb_library(lldbPluginCPlusPlusLanguage LibCxxUnorderedMap.cpp LibCxxVector.cpp LibStdcpp.cpp - LibStdcppSmartPointer.cpp LibStdcppTuple.cpp LibStdcppUniquePointer.cpp ) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 979ca6e..2215b92 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -63,6 +63,21 @@ private: lldb::ValueObjectSP m_pair_sp; }; +class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(const ConstString &name) override; +}; + } // end of anonymous namespace LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd( @@ -336,3 +351,80 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider( } return false; } + +LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd( + lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp) { + if (valobj_sp) + Update(); +} + +size_t LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { return 1; } + +lldb::ValueObjectSP +LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { + ValueObjectSP valobj_sp = m_backend.GetSP(); + if (!valobj_sp) + return lldb::ValueObjectSP(); + + if (idx == 0) + return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true); + else + return lldb::ValueObjectSP(); +} + +bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { return false; } + +bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; } + +size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName( + const ConstString &name) { + if (name == ConstString("_M_ptr")) + return 0; + return UINT32_MAX; +} + +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator( + CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { + return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp) + : nullptr); +} + +bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + if (!valobj_sp) + return false; + + ValueObjectSP ptr_sp( + valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true)); + if (!ptr_sp) + return false; + + ValueObjectSP usecount_sp(valobj_sp->GetChildAtNamePath( + {ConstString("_M_refcount"), ConstString("_M_pi"), + ConstString("_M_use_count")})); + if (!usecount_sp) + return false; + + if (ptr_sp->GetValueAsUnsigned(0) == 0 || + usecount_sp->GetValueAsUnsigned(0) == 0) { + stream.Printf("nullptr"); + return true; + } + + Error error; + ValueObjectSP pointee_sp = ptr_sp->Dereference(error); + if (pointee_sp && error.Success()) { + if (pointee_sp->DumpPrintableRepresentation( + stream, ValueObject::eValueObjectRepresentationStyleSummary, + lldb::eFormatInvalid, + ValueObject::ePrintableRepresentationSpecialCasesDisable, false)) { + return true; + } + } + + stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); + return true; +} diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppSmartPointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppSmartPointer.cpp deleted file mode 100644 index 4edeaab..0000000 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppSmartPointer.cpp +++ /dev/null @@ -1,200 +0,0 @@ -//===-- LibStdcppSmartPointer.cpp -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LibStdcpp.h" - -#include "lldb/Core/ConstString.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/DataFormatters/TypeSynthetic.h" -#include "lldb/Target/Target.h" - -#include -#include - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::formatters; - -namespace { - -class SharedPtrFrontEnd : public SyntheticChildrenFrontEnd { -public: - explicit SharedPtrFrontEnd(lldb::ValueObjectSP valobj_sp); - - size_t CalculateNumChildren() override; - - lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; - - bool Update() override; - - bool MightHaveChildren() override; - - size_t GetIndexOfChildWithName(const ConstString &name) override; - - bool GetSummary(Stream &stream, const TypeSummaryOptions &options); - -private: - ValueObjectSP m_ptr_obj; - ValueObjectSP m_obj_obj; - ValueObjectSP m_use_obj; - ValueObjectSP m_weak_obj; - - uint8_t m_ptr_size = 0; - lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid; - - bool IsEmpty(); - bool IsValid(); -}; - -} // end of anonymous namespace - -SharedPtrFrontEnd::SharedPtrFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp) { - Update(); -} - -bool SharedPtrFrontEnd::Update() { - ValueObjectSP valobj_backend_sp = m_backend.GetSP(); - if (!valobj_backend_sp) - return false; - - ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue(); - if (!valobj_sp) - return false; - - TargetSP target_sp(valobj_sp->GetTargetSP()); - if (!target_sp) - return false; - - m_byte_order = target_sp->GetArchitecture().GetByteOrder(); - m_ptr_size = target_sp->GetArchitecture().GetAddressByteSize(); - - m_ptr_obj = valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true); - - m_use_obj = valobj_sp->GetChildAtNamePath({ConstString("_M_refcount"), - ConstString("_M_pi"), - ConstString("_M_use_count")}); - - m_weak_obj = valobj_sp->GetChildAtNamePath({ConstString("_M_refcount"), - ConstString("_M_pi"), - ConstString("_M_weak_count")}); - - // libstdc++ implements the weak usage count in a way that it is offset by 1 - // if the strong count is not 0 (as part of a preformance optimization). We - // want to undo this before showing the weak count to the user as an offseted - // weak count would be very confusing. - if (m_use_obj && m_weak_obj && m_use_obj->GetValueAsUnsigned(0) > 0) { - bool success = false; - uint64_t count = m_weak_obj->GetValueAsUnsigned(0, &success) - 1; - if (success) { - auto data = std::make_shared(&count, sizeof(count)); - m_weak_obj = CreateValueObjectFromData( - "weak_count", DataExtractor(data, m_byte_order, m_ptr_size), - m_weak_obj->GetExecutionContextRef(), m_weak_obj->GetCompilerType()); - } - } - - if (m_ptr_obj && !IsEmpty()) { - Error error; - m_obj_obj = m_ptr_obj->Dereference(error); - if (error.Success()) { - m_obj_obj->SetName(ConstString("object")); - } - } - - return false; -} - -bool SharedPtrFrontEnd::MightHaveChildren() { return true; } - -lldb::ValueObjectSP SharedPtrFrontEnd::GetChildAtIndex(size_t idx) { - if (idx == 0) - return m_obj_obj; - if (idx == 1) - return m_ptr_obj; - if (idx == 2) - return m_use_obj; - if (idx == 3) - return m_weak_obj; - return lldb::ValueObjectSP(); -} - -size_t SharedPtrFrontEnd::CalculateNumChildren() { - if (IsEmpty()) - return 0; - return 1; -} - -size_t SharedPtrFrontEnd::GetIndexOfChildWithName(const ConstString &name) { - if (name == ConstString("obj") || name == ConstString("object")) - return 0; - if (name == ConstString("ptr") || name == ConstString("pointer") || - name == ConstString("_M_ptr")) - return 1; - if (name == ConstString("cnt") || name == ConstString("count") || - name == ConstString("use_count") || name == ConstString("strong") || - name == ConstString("_M_use_count")) - return 2; - if (name == ConstString("weak") || name == ConstString("weak_count") || - name == ConstString("_M_weak_count")) - return 3; - return UINT32_MAX; -} - -bool SharedPtrFrontEnd::GetSummary(Stream &stream, - const TypeSummaryOptions &options) { - if (!IsValid()) - return false; - - if (IsEmpty()) { - stream.Printf("nullptr"); - } else { - Error error; - bool print_pointee = false; - if (m_obj_obj) { - if (m_obj_obj->DumpPrintableRepresentation( - stream, ValueObject::eValueObjectRepresentationStyleSummary, - lldb::eFormatInvalid, - ValueObject::ePrintableRepresentationSpecialCasesDisable, - false)) { - print_pointee = true; - } - } - if (!print_pointee) - stream.Printf("ptr = 0x%" PRIx64, m_ptr_obj->GetValueAsUnsigned(0)); - } - - if (m_use_obj && m_use_obj->GetError().Success()) - stream.Printf(" strong=%" PRIu64, m_use_obj->GetValueAsUnsigned(0)); - - if (m_weak_obj && m_weak_obj->GetError().Success()) - stream.Printf(" weak=%" PRIu64, m_weak_obj->GetValueAsUnsigned(0)); - - return true; -} - -bool SharedPtrFrontEnd::IsValid() { return m_ptr_obj != nullptr; } - -bool SharedPtrFrontEnd::IsEmpty() { - return !IsValid() || m_ptr_obj->GetValueAsUnsigned(0) == 0 || - (m_use_obj && m_use_obj->GetValueAsUnsigned(0) == 0); -} - -SyntheticChildrenFrontEnd * -lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator( - CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - return valobj_sp ? new SharedPtrFrontEnd(valobj_sp) : nullptr; -} - -bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - SharedPtrFrontEnd formatter(valobj.GetSP()); - return formatter.GetSummary(stream, options); -} -- 2.7.4