From 3b7ac5b295df7381cee277342085f52fe468e633 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Thu, 8 Dec 2022 11:00:08 -0800 Subject: [PATCH] Fix GetAddressOf for children of pointer ValueObjectConstResult* variables. The original code always set the m_live_address of children of the ValueObjects that use ValueObjectConstResultImpl backends to the parent m_live_address + child_byte_offset. That is correct for structure types, but wrong for pointer types, since m_live_address for a pointer type is the address of the storage for the pointer, not of the pointee. Also added a test which was failing before this patch. --- lldb/source/Core/ValueObjectConstResultImpl.cpp | 15 ++++++--- .../test/API/lang/c/parray_vrs_char_array/Makefile | 4 +++ .../TestParrayVrsCharArrayChild.py | 37 ++++++++++++++++++++++ lldb/test/API/lang/c/parray_vrs_char_array/main.c | 15 +++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 lldb/test/API/lang/c/parray_vrs_char_array/Makefile create mode 100644 lldb/test/API/lang/c/parray_vrs_char_array/TestParrayVrsCharArrayChild.py create mode 100644 lldb/test/API/lang/c/parray_vrs_char_array/main.c diff --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp index fee1da1..e2db3ac 100644 --- a/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -89,13 +89,20 @@ ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex( if (!child_name_str.empty()) child_name.SetCString(child_name_str.c_str()); + lldb::addr_t child_live_addr = LLDB_INVALID_ADDRESS; + // Transfer the live address (with offset) to the child. But if + // the parent is a pointer, the live address is where that pointer + // value lives in memory, so the children live addresses aren't + // offsets from that value, they are just other load addresses that + // are recorded in the Value of the child ValueObjects. + if (m_live_address != LLDB_INVALID_ADDRESS) { + if (!compiler_type.IsPointerType()) + child_live_addr = m_live_address + child_byte_offset; + } valobj = new ValueObjectConstResultChild( *m_impl_backend, child_compiler_type, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, - child_is_base_class, child_is_deref_of_parent, - m_live_address == LLDB_INVALID_ADDRESS - ? m_live_address - : m_live_address + child_byte_offset, + child_is_base_class, child_is_deref_of_parent, child_live_addr, language_flags); } diff --git a/lldb/test/API/lang/c/parray_vrs_char_array/Makefile b/lldb/test/API/lang/c/parray_vrs_char_array/Makefile new file mode 100644 index 0000000..695335e --- /dev/null +++ b/lldb/test/API/lang/c/parray_vrs_char_array/Makefile @@ -0,0 +1,4 @@ +C_SOURCES := main.c +CFLAGS_EXTRAS := -std=c99 + +include Makefile.rules diff --git a/lldb/test/API/lang/c/parray_vrs_char_array/TestParrayVrsCharArrayChild.py b/lldb/test/API/lang/c/parray_vrs_char_array/TestParrayVrsCharArrayChild.py new file mode 100644 index 0000000..f179551 --- /dev/null +++ b/lldb/test/API/lang/c/parray_vrs_char_array/TestParrayVrsCharArrayChild.py @@ -0,0 +1,37 @@ +""" +Test that parray of a struct with an embedded char array works. +This was failing because the "live address" of the child elements +was calculated incorrectly - as a offset from the pointer live +address. It only happened for char[] children because they used +GetAddressOf which relies on the live address. +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class TestParrayVrsCharArrayChild(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + + def test_parray_struct_with_char_array_child(self): + """This is the basic test for does parray get the char values right.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + self.do_array_test() + + def do_array_test(self): + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + + frame = thread.GetFrameAtIndex(0) + + self.expect("expr -Z 3 -- struct_ptr", + substrs = ['before = 112, var = "abcd", after = 221', + 'before = 313, var = "efgh", after = 414', + 'before = 515, var = "ijkl", after = 616']) + + diff --git a/lldb/test/API/lang/c/parray_vrs_char_array/main.c b/lldb/test/API/lang/c/parray_vrs_char_array/main.c new file mode 100644 index 0000000..0571a6b --- /dev/null +++ b/lldb/test/API/lang/c/parray_vrs_char_array/main.c @@ -0,0 +1,15 @@ +struct MyStruct { + int before; + char var[5]; + int after; +}; + +int +main() +{ + struct MyStruct struct_arr[3] = {{112, "abcd", 221}, + {313, "efgh", 414}, + {515, "ijkl", 616}}; + struct MyStruct *struct_ptr = struct_arr; + return struct_ptr->before; // Set a breakpoint here +} -- 2.7.4