Skip to content

Conversation

@Michael137
Copy link
Member

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.

…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.
@Michael137 Michael137 requested a review from labath July 4, 2025 10:24
@Michael137 Michael137 requested a review from JDevlieghere as a code owner July 4, 2025 10:24
@llvmbot llvmbot added the lldb label Jul 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 4, 2025

@llvm/pr-subscribers-lldb

Author: Michael Buch (Michael137)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/147033.diff

3 Files Affected:

  • (modified) lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp (+6-1)
  • (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py (+20-8)
  • (modified) lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp (+9-1)
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;
 }

@Michael137 Michael137 merged commit 32946eb into llvm:main Jul 4, 2025
11 checks passed
@Michael137 Michael137 deleted the lldb/formatter-weak-count-fix branch July 4, 2025 14:31
Michael137 added a commit to swiftlang/llvm-project that referenced this pull request Jul 25, 2025
…weak_ptr (llvm#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.

(cherry picked from commit 32946eb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants