https://github.com/igorkudrin updated https://github.com/llvm/llvm-project/pull/212915
>From 4297ccab6b50e388549cc0556fb50dc7cae4c0e4 Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Mon, 27 Jul 2026 15:31:52 -0700 Subject: [PATCH 1/4] [lldb] Avoid returning a stale AddressOf The 'ValueObject::AddressOf()' method assumes that the address of a value object cannot change, so when it is calculated once, it does not need to be updated afterwards. However, this is not the case if the 'ValueObject' is a dependent object obtained by calling 'Dereference()' of another 'ValueObject'. If the latter object is changed, the dependent value object should return a new address from the 'AddressOf()' method to reflect the change. --- lldb/source/ValueObject/ValueObject.cpp | 7 +++--- .../API/python_api/value/change_ptr/Makefile | 3 +++ .../value/change_ptr/TestChangePtr.py | 22 +++++++++++++++++++ .../API/python_api/value/change_ptr/main.c | 7 ++++++ 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 lldb/test/API/python_api/value/change_ptr/Makefile create mode 100644 lldb/test/API/python_api/value/change_ptr/TestChangePtr.py create mode 100644 lldb/test/API/python_api/value/change_ptr/main.c diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp index e2bfa02500f2c..b36a020d262c4 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -2913,9 +2913,6 @@ ValueObjectSP ValueObject::Dereference(Status &error) { } ValueObjectSP ValueObject::AddressOf(Status &error) { - if (m_addr_of_valobj_sp) - return m_addr_of_valobj_sp; - auto [addr, address_type] = GetAddressOf(/*scalar_is_load_address=*/false); error.Clear(); if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) { @@ -2929,6 +2926,10 @@ ValueObjectSP ValueObject::AddressOf(Status &error) { case eAddressTypeFile: case eAddressTypeLoad: { + if (m_addr_of_valobj_sp && + m_addr_of_valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS) == addr) + return m_addr_of_valobj_sp; + m_addr_of_valobj_sp.reset(); CompilerType compiler_type = GetCompilerType(); if (compiler_type) { std::string name(1, '&'); diff --git a/lldb/test/API/python_api/value/change_ptr/Makefile b/lldb/test/API/python_api/value/change_ptr/Makefile new file mode 100644 index 0000000000000..10495940055b6 --- /dev/null +++ b/lldb/test/API/python_api/value/change_ptr/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py b/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py new file mode 100644 index 0000000000000..378332568e097 --- /dev/null +++ b/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py @@ -0,0 +1,22 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ChangePtrTest(TestBase): + + def test(self): + self.build() + + _, _, thread, _ = lldbutil.run_to_source_breakpoint( + self, "// break here", lldb.SBFileSpec("main.c") + ) + frame = thread.GetFrameAtIndex(0) + p = frame.FindVariable("p") + deref = p.Dereference() + self.assertEqual(deref.GetValueAsUnsigned(), 5) + self.assertEqual(deref.AddressOf().GetValueAsUnsigned(), p.GetValueAsUnsigned()) + thread.StepOver() + self.assertEqual(deref.GetValueAsUnsigned(), 7) + self.assertEqual(deref.AddressOf().GetValueAsUnsigned(), p.GetValueAsUnsigned()) diff --git a/lldb/test/API/python_api/value/change_ptr/main.c b/lldb/test/API/python_api/value/change_ptr/main.c new file mode 100644 index 0000000000000..15f223ae2577a --- /dev/null +++ b/lldb/test/API/python_api/value/change_ptr/main.c @@ -0,0 +1,7 @@ +int main() { + int a = 5; + int b = 7; + int *p = &a; + p = &b; // break here + return 0; +} >From 7b30f8055baeff02907814db4f61e74f9535d128 Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Wed, 29 Jul 2026 19:09:20 -0700 Subject: [PATCH 2/4] fixup! formatting --- lldb/test/API/python_api/value/change_ptr/TestChangePtr.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py b/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py index 378332568e097..ae9cf309ab0dd 100644 --- a/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py +++ b/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py @@ -5,7 +5,6 @@ class ChangePtrTest(TestBase): - def test(self): self.build() >From 7bd061ca17554bba3fdda45e5ab38885ff5c70bf Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Fri, 31 Jul 2026 00:20:33 -0700 Subject: [PATCH 3/4] fixup! Add more tests --- .../value/change_ptr/TestChangePtr.py | 48 ++++++++++++++++++- .../API/python_api/value/change_ptr/main.c | 25 +++++++++- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py b/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py index ae9cf309ab0dd..f68eeb8404d70 100644 --- a/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py +++ b/lldb/test/API/python_api/value/change_ptr/TestChangePtr.py @@ -8,9 +8,14 @@ class ChangePtrTest(TestBase): def test(self): self.build() - _, _, thread, _ = lldbutil.run_to_source_breakpoint( - self, "// break here", lldb.SBFileSpec("main.c") + src_file = lldb.SBFileSpec("main.c") + _, process, thread, _ = lldbutil.run_to_source_breakpoint( + self, "// break here 1", src_file ) + + ## Test 1: The AddressOf of a dereferenced value should change when + ## the pointer value is updated. + frame = thread.GetFrameAtIndex(0) p = frame.FindVariable("p") deref = p.Dereference() @@ -19,3 +24,42 @@ def test(self): thread.StepOver() self.assertEqual(deref.GetValueAsUnsigned(), 7) self.assertEqual(deref.AddressOf().GetValueAsUnsigned(), p.GetValueAsUnsigned()) + + ## Test 2: The AddressOf of a child value of a dereferenced value should + ## change when the base pointer updates. + + lldbutil.continue_to_source_breakpoint( + self, process, "// break here 2", src_file + ) + frame = thread.GetFrameAtIndex(0) + p = frame.FindVariable("p") + deref_child = p.Dereference().GetChildMemberWithName("b") + self.assertEqual(deref_child.GetValue(), "'b'") + self.assertEqual( + deref_child.AddressOf().GetValueAsUnsigned(), p.GetValueAsUnsigned() + 1 + ) + thread.StepOver() + self.assertEqual(deref_child.GetValue(), "'d'") + self.assertEqual( + deref_child.AddressOf().GetValueAsUnsigned(), p.GetValueAsUnsigned() + 1 + ) + + ## Test 3: Verify AddressOf updates correctly with persistent expression results. + lldbutil.continue_to_source_breakpoint( + self, process, "// break here 3", src_file + ) + frame = thread.GetFrameAtIndex(0) + frame.EvaluateExpression("int *$ptr = &a") + ptr = frame.FindValue("$ptr", lldb.eValueTypeConstResult) + deref = ptr.Dereference() + self.assertEqual(deref.GetValueAsUnsigned(), 5) + self.assertEqual( + deref.AddressOf().GetValueAsUnsigned(), + frame.FindVariable("a").AddressOf().GetValueAsUnsigned(), + ) + frame.EvaluateExpression("$ptr = &b") + self.assertEqual(deref.GetValueAsUnsigned(), 7) + self.assertEqual( + deref.AddressOf().GetValueAsUnsigned(), + frame.FindVariable("b").AddressOf().GetValueAsUnsigned(), + ) diff --git a/lldb/test/API/python_api/value/change_ptr/main.c b/lldb/test/API/python_api/value/change_ptr/main.c index 15f223ae2577a..24062fb6db8d0 100644 --- a/lldb/test/API/python_api/value/change_ptr/main.c +++ b/lldb/test/API/python_api/value/change_ptr/main.c @@ -1,7 +1,28 @@ -int main() { +int test1() { int a = 5; int b = 7; int *p = &a; - p = &b; // break here + p = &b; // break here 1 + return *p; +} + +char test2() { + struct S {char a; char b; }; + struct S arr[2] = {{'a', 'b'}, {'c', 'd'}}; + struct S *p = arr; + ++p; // break here 2 + return p->b; +} + +int test3() { + int a = 5; + int b = 7; + return a + b; // break here 3 +} + +int main() { + test1(); + test2(); + test3(); return 0; } >From c40dac9aa0ed4260940ee53eab8fa9691eb50675 Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Fri, 31 Jul 2026 00:26:38 -0700 Subject: [PATCH 4/4] fixup! formatting --- lldb/test/API/python_api/value/change_ptr/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/python_api/value/change_ptr/main.c b/lldb/test/API/python_api/value/change_ptr/main.c index 24062fb6db8d0..4cce83e61476c 100644 --- a/lldb/test/API/python_api/value/change_ptr/main.c +++ b/lldb/test/API/python_api/value/change_ptr/main.c @@ -7,7 +7,10 @@ int test1() { } char test2() { - struct S {char a; char b; }; + struct S { + char a; + char b; + }; struct S arr[2] = {{'a', 'b'}, {'c', 'd'}}; struct S *p = arr; ++p; // break here 2 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
