[Lldb-commits] [lldb] [lldb][Formatters] Fix weak reference count for std::shared_ptr/std::weak_ptr (PR #147033)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 4 03:24:53 PDT 2025
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/147033
For the `__shared_owners_` we need to add `+1` to the count, but for `__shared_weak_owners_` the value reflects the exact number of weak references.
>From 6700e8ba954d0ce29b8703ec35a992e93bf1dfdc Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 4 Jul 2025 11:22:57 +0100
Subject: [PATCH] [lldb][Formatters] Fix weak reference count for
std::shared_ptr/std::weak_ptr
For the `__shared_owners_` we need to add `+1` to the count, but for
`__shared_weak_owners_` the value reflects the exact number of weak
references.
---
.../Plugins/Language/CPlusPlus/LibCxx.cpp | 7 ++++-
.../TestDataFormatterLibcxxSharedPtr.py | 28 +++++++++++++------
.../libcxx/shared_ptr/main.cpp | 10 ++++++-
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 009586f525282..104521b8c3e71 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -177,6 +177,9 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
if (!success)
return false;
+ // std::shared_ptr releases the underlying resource when the
+ // __shared_owners_ count hits -1. So `__shared_owners_ == 0` indicates 1
+ // owner. Hence add +1 here.
stream.Printf(" strong=%" PRIu64, count + 1);
}
@@ -187,7 +190,9 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
if (!success)
return false;
- stream.Printf(" weak=%" PRIu64, count + 1);
+ // Unlike __shared_owners_, __shared_weak_owners_ indicates the exact
+ // std::weak_ptr reference count.
+ stream.Printf(" weak=%" PRIu64, count);
}
return true;
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py
index 6ecf5ca88e90e..25f616ff61046 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py
@@ -14,7 +14,7 @@ def test_shared_ptr_variables(self):
"""Test `frame variable` output for `std::shared_ptr` types."""
self.build()
- lldbutil.run_to_source_breakpoint(
+ (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(
self, "// break here", lldb.SBFileSpec("main.cpp")
)
@@ -37,7 +37,7 @@ def test_shared_ptr_variables(self):
type="std::shared_ptr<int>",
children=[ValueCheck(name="__ptr_")],
)
- self.assertRegex(valobj.summary, r"^10( strong=1)? weak=1$")
+ self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
self.assertNotEqual(valobj.child[0].unsigned, 0)
valobj = self.expect_var_path(
@@ -45,7 +45,7 @@ def test_shared_ptr_variables(self):
type="std::shared_ptr<int> &",
children=[ValueCheck(name="__ptr_")],
)
- self.assertRegex(valobj.summary, r"^10( strong=1)? weak=1$")
+ self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
self.assertNotEqual(valobj.child[0].unsigned, 0)
valobj = self.expect_var_path(
@@ -53,7 +53,7 @@ def test_shared_ptr_variables(self):
type="std::shared_ptr<int> &&",
children=[ValueCheck(name="__ptr_")],
)
- self.assertRegex(valobj.summary, r"^10( strong=1)? weak=1$")
+ self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
self.assertNotEqual(valobj.child[0].unsigned, 0)
if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(
@@ -68,12 +68,12 @@ def test_shared_ptr_variables(self):
type="std::shared_ptr<" + string_type + ">",
children=[ValueCheck(name="__ptr_", summary='"hello"')],
)
- self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=1$')
+ self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=0$')
valobj = self.expect_var_path("sp_user", type="std::shared_ptr<User>")
self.assertRegex(
valobj.summary,
- "^std(::__[^:]*)?::shared_ptr<User>::element_type @ 0x0*[1-9a-f][0-9a-f]+( strong=1)? weak=1",
+ "^std(::__[^:]*)?::shared_ptr<User>::element_type @ 0x0*[1-9a-f][0-9a-f]+( strong=1)? weak=0",
)
self.assertNotEqual(valobj.child[0].unsigned, 0)
@@ -91,11 +91,23 @@ def test_shared_ptr_variables(self):
self.expect_var_path("sp_user->name", type="std::string", summary='"steph"')
valobj = self.expect_var_path(
- "si", type="std::shared_ptr<int>", summary="47 strong=2 weak=1"
+ "si", type="std::shared_ptr<int>", summary="47 strong=2 weak=0"
)
valobj = self.expect_var_path(
- "sie", type="std::shared_ptr<int>", summary="nullptr strong=2 weak=1"
+ "sie", type="std::shared_ptr<int>", summary="nullptr strong=2 weak=0"
+ )
+
+ lldbutil.continue_to_breakpoint(process, bkpt)
+
+ valobj = self.expect_var_path(
+ "si", type="std::shared_ptr<int>", summary="47 strong=2 weak=2"
+ )
+ valobj = self.expect_var_path(
+ "sie", type="std::shared_ptr<int>", summary="nullptr strong=2 weak=2"
+ )
+ valobj = self.expect_var_path(
+ "wie", type="std::weak_ptr<int>", summary="nullptr strong=2 weak=2"
)
self.runCmd("settings set target.experimental.use-DIL true")
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp
index 3ac86a3ee9843..cfefaf37a5dbd 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp
@@ -1,3 +1,4 @@
+#include <cstdio>
#include <memory>
#include <string>
@@ -26,5 +27,12 @@ int main() {
std::shared_ptr<int> si(new int(47));
std::shared_ptr<int> sie(si, nullptr);
- return 0; // break here
+ std::puts("// break here");
+
+ std::weak_ptr<int> wie = sie;
+ std::weak_ptr<int> wie2 = sie;
+
+ std::puts("// break here");
+
+ return 0;
}
More information about the lldb-commits
mailing list