[Lldb-commits] [lldb] 3b7ac5b - Fix GetAddressOf for children of pointer ValueObjectConstResult* variables.

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 9 11:16:21 PST 2022


Author: Jim Ingham
Date: 2022-12-09T11:16:10-08:00
New Revision: 3b7ac5b295df7381cee277342085f52fe468e633

URL: https://github.com/llvm/llvm-project/commit/3b7ac5b295df7381cee277342085f52fe468e633
DIFF: https://github.com/llvm/llvm-project/commit/3b7ac5b295df7381cee277342085f52fe468e633.diff

LOG: 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.

Added: 
    lldb/test/API/lang/c/parray_vrs_char_array/Makefile
    lldb/test/API/lang/c/parray_vrs_char_array/TestParrayVrsCharArrayChild.py
    lldb/test/API/lang/c/parray_vrs_char_array/main.c

Modified: 
    lldb/source/Core/ValueObjectConstResultImpl.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp
index fee1da138bbc6..e2db3ace19247 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 0000000000000..695335e068c0c
--- /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 0000000000000..f1795516c74e1
--- /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 0000000000000..0571a6bc5f66d
--- /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
+}


        


More information about the lldb-commits mailing list