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. (cherry picked from commit 320164daab4148e3372f6756caaa67882e24a91f)
66 lines
2.5 KiB
Python
66 lines
2.5 KiB
Python
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()
|
|
|
|
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()
|
|
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())
|
|
|
|
## 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(),
|
|
)
|