Skip to content

Commit 32946eb

Browse files
authored
[lldb][Formatters] Fix weak reference count for std::shared_ptr/std::weak_ptr (#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.
1 parent 9fcea2e commit 32946eb

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
177177
if (!success)
178178
return false;
179179

180+
// std::shared_ptr releases the underlying resource when the
181+
// __shared_owners_ count hits -1. So `__shared_owners_ == 0` indicates 1
182+
// owner. Hence add +1 here.
180183
stream.Printf(" strong=%" PRIu64, count + 1);
181184
}
182185

@@ -187,7 +190,9 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
187190
if (!success)
188191
return false;
189192

190-
stream.Printf(" weak=%" PRIu64, count + 1);
193+
// Unlike __shared_owners_, __shared_weak_owners_ indicates the exact
194+
// std::weak_ptr reference count.
195+
stream.Printf(" weak=%" PRIu64, count);
191196
}
192197

193198
return true;

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/TestDataFormatterLibcxxSharedPtr.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def test_shared_ptr_variables(self):
1414
"""Test `frame variable` output for `std::shared_ptr` types."""
1515
self.build()
1616

17-
lldbutil.run_to_source_breakpoint(
17+
(_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(
1818
self, "// break here", lldb.SBFileSpec("main.cpp")
1919
)
2020

@@ -37,23 +37,23 @@ def test_shared_ptr_variables(self):
3737
type="std::shared_ptr<int>",
3838
children=[ValueCheck(name="__ptr_")],
3939
)
40-
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=1$")
40+
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
4141
self.assertNotEqual(valobj.child[0].unsigned, 0)
4242

4343
valobj = self.expect_var_path(
4444
"sp_int_ref",
4545
type="std::shared_ptr<int> &",
4646
children=[ValueCheck(name="__ptr_")],
4747
)
48-
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=1$")
48+
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
4949
self.assertNotEqual(valobj.child[0].unsigned, 0)
5050

5151
valobj = self.expect_var_path(
5252
"sp_int_ref_ref",
5353
type="std::shared_ptr<int> &&",
5454
children=[ValueCheck(name="__ptr_")],
5555
)
56-
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=1$")
56+
self.assertRegex(valobj.summary, r"^10( strong=1)? weak=0$")
5757
self.assertNotEqual(valobj.child[0].unsigned, 0)
5858

5959
if self.expectedCompiler(["clang"]) and self.expectedCompilerVersion(
@@ -68,12 +68,12 @@ def test_shared_ptr_variables(self):
6868
type="std::shared_ptr<" + string_type + ">",
6969
children=[ValueCheck(name="__ptr_", summary='"hello"')],
7070
)
71-
self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=1$')
71+
self.assertRegex(valobj.summary, r'^"hello"( strong=1)? weak=0$')
7272

7373
valobj = self.expect_var_path("sp_user", type="std::shared_ptr<User>")
7474
self.assertRegex(
7575
valobj.summary,
76-
"^std(::__[^:]*)?::shared_ptr<User>::element_type @ 0x0*[1-9a-f][0-9a-f]+( strong=1)? weak=1",
76+
"^std(::__[^:]*)?::shared_ptr<User>::element_type @ 0x0*[1-9a-f][0-9a-f]+( strong=1)? weak=0",
7777
)
7878
self.assertNotEqual(valobj.child[0].unsigned, 0)
7979

@@ -91,11 +91,23 @@ def test_shared_ptr_variables(self):
9191
self.expect_var_path("sp_user->name", type="std::string", summary='"steph"')
9292

9393
valobj = self.expect_var_path(
94-
"si", type="std::shared_ptr<int>", summary="47 strong=2 weak=1"
94+
"si", type="std::shared_ptr<int>", summary="47 strong=2 weak=0"
9595
)
9696

9797
valobj = self.expect_var_path(
98-
"sie", type="std::shared_ptr<int>", summary="nullptr strong=2 weak=1"
98+
"sie", type="std::shared_ptr<int>", summary="nullptr strong=2 weak=0"
99+
)
100+
101+
lldbutil.continue_to_breakpoint(process, bkpt)
102+
103+
valobj = self.expect_var_path(
104+
"si", type="std::shared_ptr<int>", summary="47 strong=2 weak=2"
105+
)
106+
valobj = self.expect_var_path(
107+
"sie", type="std::shared_ptr<int>", summary="nullptr strong=2 weak=2"
108+
)
109+
valobj = self.expect_var_path(
110+
"wie", type="std::weak_ptr<int>", summary="nullptr strong=2 weak=2"
99111
)
100112

101113
self.runCmd("settings set target.experimental.use-DIL true")

lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/shared_ptr/main.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <cstdio>
12
#include <memory>
23
#include <string>
34

@@ -26,5 +27,12 @@ int main() {
2627
std::shared_ptr<int> si(new int(47));
2728
std::shared_ptr<int> sie(si, nullptr);
2829

29-
return 0; // break here
30+
std::puts("// break here");
31+
32+
std::weak_ptr<int> wie = sie;
33+
std::weak_ptr<int> wie2 = sie;
34+
35+
std::puts("// break here");
36+
37+
return 0;
3038
}

0 commit comments

Comments
 (0)