https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/147166
>From f9be1d811b66b050a79f83c16c7b404948c37505 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Sat, 5 Jul 2025 12:42:39 +0100 Subject: [PATCH 1/3] [lldb][Formatters] Make libc++ and libstdc++ std::shared_ptr formatters consistent with each other --- .../Plugins/Language/CPlusPlus/LibCxx.cpp | 39 +++++++++++-------- .../Plugins/Language/CPlusPlus/LibCxx.h | 1 + .../Plugins/Language/CPlusPlus/LibStdcpp.cpp | 27 +++++++------ 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 104521b8c3e71..aa13e66a1b550 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -238,7 +238,8 @@ lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator( lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: LibcxxSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr) { + : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr), + m_ptr_obj(nullptr) { if (valobj_sp) Update(); } @@ -251,7 +252,7 @@ llvm::Expected<uint32_t> lldb_private::formatters:: lldb::ValueObjectSP lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex( uint32_t idx) { - if (!m_cntrl) + if (!m_cntrl || !m_ptr_obj) return lldb::ValueObjectSP(); ValueObjectSP valobj_sp = m_backend.GetSP(); @@ -259,20 +260,17 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex( return lldb::ValueObjectSP(); if (idx == 0) - return valobj_sp->GetChildMemberWithName("__ptr_"); + return m_ptr_obj->GetSP(); if (idx == 1) { - if (auto ptr_sp = valobj_sp->GetChildMemberWithName("__ptr_")) { - Status status; - auto value_type_sp = - valobj_sp->GetCompilerType() - .GetTypeTemplateArgument(0).GetPointerType(); - ValueObjectSP cast_ptr_sp = ptr_sp->Cast(value_type_sp); - ValueObjectSP value_sp = cast_ptr_sp->Dereference(status); - if (status.Success()) { - return value_sp; - } - } + Status status; + auto value_type_sp = valobj_sp->GetCompilerType() + .GetTypeTemplateArgument(0) + .GetPointerType(); + ValueObjectSP cast_ptr_sp = m_ptr_obj->Cast(value_type_sp); + ValueObjectSP value_sp = cast_ptr_sp->Dereference(status); + if (status.Success()) + return value_sp; } return lldb::ValueObjectSP(); @@ -281,6 +279,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex( lldb::ChildCacheState lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { m_cntrl = nullptr; + m_ptr_obj = nullptr; ValueObjectSP valobj_sp = m_backend.GetSP(); if (!valobj_sp) @@ -290,6 +289,12 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { if (!target_sp) return lldb::ChildCacheState::eRefetch; + auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("__ptr_"); + if (!ptr_obj_sp) + return lldb::ChildCacheState::eRefetch; + + m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get(); + lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName("__cntrl_")); m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular @@ -300,10 +305,12 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { llvm::Expected<size_t> lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { - if (name == "__ptr_") + if (name == "__ptr_" || name == "pointer") return 0; - if (name == "$$dereference$$") + + if (name == "object" || name == "$$dereference$$") return 1; + return llvm::createStringError("Type has no child named '%s'", name.AsCString()); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h index 56501302d116f..6115ccde38ad2 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -108,6 +108,7 @@ class LibcxxSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { private: ValueObject *m_cntrl; + ValueObject *m_ptr_obj; }; class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 28b7c01ab1b5b..7668a87ce447e 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -77,8 +77,7 @@ class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { // objects are only destroyed when every shared pointer to any of them // is destroyed, so we must not store a shared pointer to any ValueObject // derived from our backend ValueObject (since we're in the same cluster). - ValueObject* m_ptr_obj = nullptr; // Underlying pointer (held, not owned) - ValueObject* m_obj_obj = nullptr; // Underlying object (held, not owned) + ValueObject *m_ptr_obj = nullptr; // Underlying pointer (held, not owned) }; } // end of anonymous namespace @@ -266,15 +265,20 @@ LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) { if (idx == 0) return m_ptr_obj->GetSP(); + if (idx == 1) { - if (m_ptr_obj && !m_obj_obj) { - Status error; - ValueObjectSP obj_obj = m_ptr_obj->Dereference(error); - if (error.Success()) - m_obj_obj = obj_obj->Clone(ConstString("object")).get(); - } - if (m_obj_obj) - return m_obj_obj->GetSP(); + ValueObjectSP valobj_sp = m_backend.GetSP(); + if (!valobj_sp) + return nullptr; + + Status status; + auto value_type_sp = valobj_sp->GetCompilerType() + .GetTypeTemplateArgument(0) + .GetPointerType(); + ValueObjectSP cast_ptr_sp = m_ptr_obj->Cast(value_type_sp); + ValueObjectSP value_sp = cast_ptr_sp->Dereference(status); + if (status.Success()) + return value_sp; } return lldb::ValueObjectSP(); } @@ -293,7 +297,6 @@ lldb::ChildCacheState LibStdcppSharedPtrSyntheticFrontEnd::Update() { return lldb::ChildCacheState::eRefetch; m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get(); - m_obj_obj = nullptr; return lldb::ChildCacheState::eRefetch; } @@ -302,8 +305,10 @@ llvm::Expected<size_t> LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) { if (name == "pointer") return 0; + if (name == "object" || name == "$$dereference$$") return 1; + return llvm::createStringError("Type has no child named '%s'", name.AsCString()); } >From 3e46a139b949dbc3d24be75540adecde3afb4e6b Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Sat, 5 Jul 2025 23:25:46 +0100 Subject: [PATCH 2/3] [lldb][Formatters] Add shared/weak count to libstdc++ std::shared_ptr summary --- .../Plugins/Language/CPlusPlus/LibStdcpp.cpp | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 7668a87ce447e..5862a1ff3eac3 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -9,6 +9,7 @@ #include "LibStdcpp.h" #include "LibCxx.h" +#include "lldb/DataFormatters/FormattersHelpers.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/VectorIterator.h" @@ -330,29 +331,37 @@ bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider( if (!ptr_sp) return false; - ValueObjectSP usecount_sp( - valobj_sp->GetChildAtNamePath({"_M_refcount", "_M_pi", "_M_use_count"})); - if (!usecount_sp) + DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options); + + ValueObjectSP pi_sp = valobj_sp->GetChildAtNamePath({"_M_refcount", "_M_pi"}); + if (!pi_sp) return false; - if (ptr_sp->GetValueAsUnsigned(0) == 0 || - usecount_sp->GetValueAsUnsigned(0) == 0) { - stream.Printf("nullptr"); + bool success; + uint64_t pi_addr = pi_sp->GetValueAsUnsigned(0, &success); + // Empty control field. We're done. + if (!success || pi_addr == 0) return true; + + int64_t shared_count = 0; + if (auto count_sp = pi_sp->GetChildMemberWithName("_M_use_count")) { + bool success; + shared_count = count_sp->GetValueAsSigned(0, &success); + if (!success) + return false; + + stream.Printf(" strong=%" PRId64, shared_count); } - Status error; - ValueObjectSP pointee_sp = ptr_sp->Dereference(error); - if (pointee_sp && error.Success()) { - if (pointee_sp->DumpPrintableRepresentation( - stream, ValueObject::eValueObjectRepresentationStyleSummary, - lldb::eFormatInvalid, - ValueObject::PrintableRepresentationSpecialCases::eDisable, - false)) { - return true; - } + // _M_weak_count is the number of weak references + (_M_use_count != 0). + if (auto weak_count_sp = pi_sp->GetChildMemberWithName("_M_weak_count")) { + bool success; + int64_t count = weak_count_sp->GetValueAsUnsigned(0, &success); + if (!success) + return false; + + stream.Printf(" weak=%" PRId64, count - (shared_count != 0)); } - stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); return true; } >From 7b20530aaa0393a37e2d12737693cd4ccfa1444f Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Sun, 6 Jul 2025 07:53:27 +0100 Subject: [PATCH 3/3] fixup! clang-format --- lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 5862a1ff3eac3..84442273aebd4 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -9,8 +9,8 @@ #include "LibStdcpp.h" #include "LibCxx.h" -#include "lldb/DataFormatters/FormattersHelpers.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/VectorIterator.h" #include "lldb/Target/Target.h" _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits