Skip to content

Reapply "Make result variables obey their dynamic values in subsequent expressions - #216771

Open
jimingham wants to merge 1 commit into
llvm:release/23.xfrom
jimingham:dyn-result-23.x
Open

Reapply "Make result variables obey their dynamic values in subsequent expressions#216771
jimingham wants to merge 1 commit into
llvm:release/23.xfrom
jimingham:dyn-result-23.x

Conversation

@jimingham

Copy link
Copy Markdown
Contributor

This adds back the patch that makes result variables retain their dynamic type when you use them in subsequent expressions or fetch their SBValues.

This reverts commit e1af868.

The first time I submitted this I had some flakey tests, but when I fixed the accounting for synthetic children those went away. But the patch was still failing in a set of ObjC tests on x86_64. Those failures weren't caused by this patch, but rather uncovered a bug in Tagged Pointer detection, which I fixed in:

#213163
(cherry picked from commit 1969f15)

…t expressions" (llvm#211321) (llvm#213308)

This adds back the patch that makes result variables retain their
dynamic type when you use them in subsequent expressions or fetch their
SBValues.

This reverts commit e1af868.

The first time I submitted this I had some flakey tests, but when I
fixed the accounting for synthetic children those went away. But the
patch was still failing in a set of ObjC tests on x86_64. Those failures
weren't caused by this patch, but rather uncovered a bug in Tagged
Pointer detection, which I fixed in:

llvm#213163
(cherry picked from commit 1969f15)
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-lldb

Author: jimingham

Changes

This adds back the patch that makes result variables retain their dynamic type when you use them in subsequent expressions or fetch their SBValues.

This reverts commit e1af868.

The first time I submitted this I had some flakey tests, but when I fixed the accounting for synthetic children those went away. But the patch was still failing in a set of ObjC tests on x86_64. Those failures weren't caused by this patch, but rather uncovered a bug in Tagged Pointer detection, which I fixed in:

#213163
(cherry picked from commit 1969f15)


Patch is 27.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/216771.diff

10 Files Affected:

  • (modified) lldb/include/lldb/Expression/ExpressionVariable.h (+45-19)
  • (modified) lldb/packages/Python/lldbsuite/test/lldbtest.py (-1)
  • (modified) lldb/source/Expression/ExpressionVariable.cpp (+72-6)
  • (modified) lldb/source/Expression/LLVMUserExpression.cpp (+9-5)
  • (modified) lldb/source/Expression/Materializer.cpp (+25-24)
  • (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp (+1-1)
  • (modified) lldb/source/Target/ABI.cpp (+1-1)
  • (added) lldb/test/API/functionalities/expr-result-var/Makefile (+3)
  • (added) lldb/test/API/functionalities/expr-result-var/TestCPPExprResult.py (+174)
  • (added) lldb/test/API/functionalities/expr-result-var/two-bases.cpp (+55)
diff --git a/lldb/include/lldb/Expression/ExpressionVariable.h b/lldb/include/lldb/Expression/ExpressionVariable.h
index 991faf17daef3..62100fcb5f527 100644
--- a/lldb/include/lldb/Expression/ExpressionVariable.h
+++ b/lldb/include/lldb/Expression/ExpressionVariable.h
@@ -33,11 +33,19 @@ class ExpressionVariable
 
   virtual ~ExpressionVariable() = default;
 
-  llvm::Expected<uint64_t> GetByteSize() { return m_frozen_sp->GetByteSize(); }
+  llvm::Expected<uint64_t> GetByteSize() {
+    return GetValueObject()->GetByteSize();
+  }
 
   ConstString GetName() { return m_frozen_sp->GetName(); }
 
-  lldb::ValueObjectSP GetValueObject() { return m_frozen_sp; }
+  lldb::ValueObjectSP GetValueObject() {
+    lldb::ValueObjectSP dyn_sp =
+        m_frozen_sp->GetDynamicValue(lldb::eDynamicDontRunTarget);
+    if (dyn_sp && dyn_sp->UpdateValueIfNeeded())
+      return dyn_sp;
+    return m_frozen_sp;
+  }
 
   uint8_t *GetValueBytes();
 
@@ -52,7 +60,7 @@ class ExpressionVariable
         Value::ContextType::RegisterInfo, const_cast<RegisterInfo *>(reg_info));
   }
 
-  CompilerType GetCompilerType() { return m_frozen_sp->GetCompilerType(); }
+  CompilerType GetCompilerType() { return GetValueObject()->GetCompilerType(); }
 
   void SetCompilerType(const CompilerType &compiler_type) {
     m_frozen_sp->GetValue().SetCompilerType(compiler_type);
@@ -60,23 +68,31 @@ class ExpressionVariable
 
   void SetName(llvm::StringRef name) { m_frozen_sp->SetName(name); }
 
-  // this function is used to copy the address-of m_live_sp into m_frozen_sp
-  // this is necessary because the results of certain cast and pointer-
-  // arithmetic operations (such as those described in bugzilla issues 11588
-  // and 11618) generate frozen objects that do not have a valid address-of,
-  // which can be troublesome when using synthetic children providers.
-  // Transferring the address-of the live object solves these issues and
-  // provides the expected user-level behavior
-  void TransferAddress(bool force = false) {
-    if (m_live_sp.get() == nullptr)
-      return;
-
-    if (m_frozen_sp.get() == nullptr)
-      return;
-
-    if (force || (m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS))
-      m_frozen_sp->SetLiveAddress(m_live_sp->GetLiveAddress());
+  /// This function is used to copy the address-of m_live_sp into m_frozen_sp.
+  /// It is necessary because the results of certain cast and pointer-
+  /// arithmetic operations (such as those described in bugzilla issues 11588
+  /// and 11618) generate frozen objects that do not have a valid address-of,
+  /// which can be troublesome when using synthetic children providers.
+  /// Transferring the address-of the live object solves these issues and
+  /// provides the expected user-level behavior.
+  /// The other job we do in TransferAddress is adjust the value in the live
+  /// address slot in the target for the "offset to top" in multiply inherited
+  /// class hierarchies.
+  void TransferAddress(bool force = false);
+
+  /// When we build an expression variable we know whether we're going to use
+  /// the static or dynamic result.  If we present the dynamic value once, we
+  /// should use the dynamic value in future references to the variable, so we
+  /// record that fact here.
+  void PreserveDynamicOption(lldb::DynamicValueType dyn_type) {
+    m_dyn_option = dyn_type;
   }
+  /// We don't try to get the dynamic value of the live object when we fetch
+  /// it here.  The live object describes the container of the value in the
+  /// target, but it's type is of the object for convenience.  So it can't
+  /// produce the dynamic value.  Instead, we use TransferAddress to adjust the
+  /// value held by the LiveObject.
+  lldb::ValueObjectSP GetLiveObject() { return m_live_sp; }
 
   enum Flags {
     EVNone = 0,
@@ -110,6 +126,14 @@ class ExpressionVariable
   /// These members should be private.
   /// @{
   /// A value object whose value's data lives in host (lldb's) memory.
+  /// The m_frozen_sp holds the data & type of the expression variable or result
+  /// in the host.  The m_frozen_sp also can present a dynamic value if one is
+  /// available.
+  /// The m_frozen_sp manages the copy of this value in m_frozen_sp that we
+  /// insert in the target so that it can be referred to in future expressions.
+  /// We don't actually use the contents of the live_sp to create the value in
+  /// the target, that comes from the frozen sp.  The live_sp is mostly to track
+  /// the target-side of the value.
   lldb::ValueObjectSP m_frozen_sp;
   /// The ValueObject counterpart to m_frozen_sp that tracks the value in
   /// inferior memory. This object may not always exist; its presence depends on
@@ -119,6 +143,8 @@ class ExpressionVariable
   /// track.
   lldb::ValueObjectSP m_live_sp;
   /// @}
+
+  lldb::DynamicValueType m_dyn_option = lldb::eNoDynamicValues;
 };
 
 /// \class ExpressionVariableList ExpressionVariable.h
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index a9c229be1a771..32fb133416dfa 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -2996,7 +2996,6 @@ def expect_expr(
         )
 
         frame = self.frame()
-
         if not options:
             options = lldb.SBExpressionOptions()
 
diff --git a/lldb/source/Expression/ExpressionVariable.cpp b/lldb/source/Expression/ExpressionVariable.cpp
index 9e8ea60f8e052..4c9568106b346 100644
--- a/lldb/source/Expression/ExpressionVariable.cpp
+++ b/lldb/source/Expression/ExpressionVariable.cpp
@@ -20,15 +20,15 @@ char ExpressionVariable::ID;
 ExpressionVariable::ExpressionVariable() : m_flags(0) {}
 
 uint8_t *ExpressionVariable::GetValueBytes() {
+  lldb::ValueObjectSP valobj_sp = GetValueObject();
   std::optional<uint64_t> byte_size =
-      llvm::expectedToOptional(m_frozen_sp->GetByteSize());
+      llvm::expectedToOptional(valobj_sp->GetByteSize());
   if (byte_size && *byte_size) {
-    if (m_frozen_sp->GetDataExtractor().GetByteSize() < *byte_size) {
-      m_frozen_sp->GetValue().ResizeData(*byte_size);
-      m_frozen_sp->GetValue().GetData(m_frozen_sp->GetDataExtractor());
+    if (valobj_sp->GetDataExtractor().GetByteSize() < *byte_size) {
+      valobj_sp->GetValue().ResizeData(*byte_size);
+      valobj_sp->GetValue().GetData(valobj_sp->GetDataExtractor());
     }
-    return const_cast<uint8_t *>(
-        m_frozen_sp->GetDataExtractor().GetDataStart());
+    return const_cast<uint8_t *>(valobj_sp->GetDataExtractor().GetDataStart());
   }
   return nullptr;
 }
@@ -37,6 +37,72 @@ char PersistentExpressionState::ID;
 
 PersistentExpressionState::PersistentExpressionState() = default;
 
+void ExpressionVariable::TransferAddress(bool force) {
+  if (!m_live_sp)
+    return;
+
+  if (!m_frozen_sp)
+    return;
+
+  if (force || (m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS)) {
+    lldb::addr_t live_addr = m_live_sp->GetLiveAddress();
+    m_frozen_sp->SetLiveAddress(live_addr);
+    // One more detail, if there's an offset_to_top in the frozen_sp, then we
+    // need to appy that offset by hand.  The live_sp can't compute this
+    // itself as its type is the type of the contained object which confuses
+    // the dynamic type calculation.  So we have to update the contents of the
+    // m_live_sp with the dynamic value.
+    // Note: We could get this right when we originally write the address, but
+    // that happens in different ways for the various flavors of
+    // Entity*::Materialize, but everything comes through here, and it's just
+    // one extra memory write.
+
+    // You can only have an "offset_to_top" with pointers or references:
+    if (!m_frozen_sp->GetCompilerType().IsPointerOrReferenceType())
+      return;
+
+    lldb::ProcessSP process_sp = m_frozen_sp->GetProcessSP();
+    // If there's no dynamic value, then there can't be an offset_to_top:
+    if (!process_sp ||
+        !process_sp->IsPossibleDynamicValue(*(m_frozen_sp.get())))
+      return;
+
+    lldb::ValueObjectSP dyn_sp = m_frozen_sp->GetDynamicValue(m_dyn_option);
+    if (!dyn_sp)
+      return;
+    ValueObject::AddrAndType static_addr = m_frozen_sp->GetPointerValue();
+    if (static_addr.type != eAddressTypeLoad)
+      return;
+
+    ValueObject::AddrAndType dynamic_addr = dyn_sp->GetPointerValue();
+    if (dynamic_addr.type != eAddressTypeLoad ||
+        static_addr.address == dynamic_addr.address)
+      return;
+
+    Status error;
+    Log *log = GetLog(LLDBLog::Expressions);
+    lldb::addr_t cur_value =
+        process_sp->ReadPointerFromMemory(live_addr, error);
+    if (error.Fail())
+      return;
+
+    if (cur_value != static_addr.address) {
+      LLDB_LOG(log,
+               "Stored value: {0} read from {1} doesn't "
+               "match static addr: {2}",
+               cur_value, live_addr, static_addr.address);
+      return;
+    }
+
+    if (!process_sp->WritePointerToMemory(live_addr, dynamic_addr.address,
+                                          error)) {
+      LLDB_LOG(log, "Got error: {0} writing dynamic value: {1} to {2}", error,
+               dynamic_addr.address, live_addr);
+      return;
+    }
+  }
+}
+
 PersistentExpressionState::~PersistentExpressionState() = default;
 
 lldb::addr_t PersistentExpressionState::LookupSymbol(ConstString name) {
diff --git a/lldb/source/Expression/LLVMUserExpression.cpp b/lldb/source/Expression/LLVMUserExpression.cpp
index d2c06cbf3ba72..eaecb3dbfe726 100644
--- a/lldb/source/Expression/LLVMUserExpression.cpp
+++ b/lldb/source/Expression/LLVMUserExpression.cpp
@@ -66,7 +66,7 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
                               ExecutionContext &exe_ctx,
                               const EvaluateExpressionOptions &options,
                               lldb::UserExpressionSP &shared_ptr_to_me,
-                              lldb::ExpressionVariableSP &result) {
+                              lldb::ExpressionVariableSP &result_sp) {
   // The expression log is quite verbose, and if you're just tracking the
   // execution of the expression, it's quite convenient to have these logs come
   // out with the STEP log as well.
@@ -254,10 +254,9 @@ LLVMUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
     }
   }
 
-  if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result,
-                           function_stack_bottom, function_stack_top)) {
+  if (FinalizeJITExecution(diagnostic_manager, exe_ctx, result_sp,
+                           function_stack_bottom, function_stack_top))
     return lldb::eExpressionCompleted;
-  }
 
   return lldb::eExpressionResultUnavailable;
 }
@@ -293,8 +292,13 @@ bool LLVMUserExpression::FinalizeJITExecution(
   result =
       GetResultAfterDematerialization(exe_ctx.GetBestExecutionContextScope());
 
-  if (result)
+  if (result) {
+    // TransferAddress also does the offset_to_top calculation, so record the
+    // dynamic option before we do that.
+    if (EvaluateExpressionOptions *options = GetOptions())
+      result->PreserveDynamicOption(options->GetUseDynamic());
     result->TransferAddress();
+  }
 
   m_dematerializer_sp.reset();
 
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 51e95d3376f72..56758fcf52b09 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -76,10 +76,11 @@ class EntityPersistentVariable : public Materializer::Entity {
 
     const bool zero_memory = false;
     IRMemoryMap::AllocationPolicy used_policy;
-    auto address_or_error = map.Malloc(
+    const uint64_t malloc_size =
         llvm::expectedToOptional(m_persistent_variable_sp->GetByteSize())
-            .value_or(0),
-        8, lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+            .value_or(0);
+    auto address_or_error = map.Malloc(
+        malloc_size, 8, lldb::ePermissionsReadable | lldb::ePermissionsWritable,
         IRMemoryMap::eAllocationPolicyMirror, zero_memory, &used_policy);
     if (!address_or_error) {
       err = Status::FromErrorStringWithFormat(
@@ -90,8 +91,9 @@ class EntityPersistentVariable : public Materializer::Entity {
     }
     lldb::addr_t mem = *address_or_error;
 
-    LLDB_LOGF(log, "Allocated %s (0x%" PRIx64 ") successfully",
-              m_persistent_variable_sp->GetName().GetCString(), mem);
+    LLDB_LOGF(
+        log, "Allocated 0x%" PRIx64 "bytes for %s (0x%" PRIx64 ") successfully",
+        malloc_size, m_persistent_variable_sp->GetName().GetCString(), mem);
 
     // Put the location of the spare memory into the live data of the
     // ValueObject.
@@ -142,12 +144,12 @@ class EntityPersistentVariable : public Materializer::Entity {
   void DestroyAllocation(IRMemoryMap &map, Status &err) {
     Status deallocate_error;
 
-    map.Free((lldb::addr_t)m_persistent_variable_sp->m_live_sp->GetValue()
-                 .GetScalar()
-                 .ULongLong(),
+    lldb::ValueObjectSP live_valobj_sp =
+        m_persistent_variable_sp->GetLiveObject();
+    map.Free((lldb::addr_t)live_valobj_sp->GetValue().GetScalar().ULongLong(),
              deallocate_error);
 
-    m_persistent_variable_sp->m_live_sp.reset();
+    live_valobj_sp.reset();
 
     if (!deallocate_error.Success()) {
       err = Status::FromErrorStringWithFormat(
@@ -179,17 +181,17 @@ class EntityPersistentVariable : public Materializer::Entity {
         return;
     }
 
+    lldb::ValueObjectSP live_valobj_sp =
+        m_persistent_variable_sp->GetLiveObject();
     if ((m_persistent_variable_sp->m_flags &
              ExpressionVariable::EVIsProgramReference &&
-         m_persistent_variable_sp->m_live_sp) ||
+         live_valobj_sp) ||
         m_persistent_variable_sp->m_flags &
             ExpressionVariable::EVIsLLDBAllocated) {
       Status write_error;
 
-      map.WriteScalarToMemory(
-          load_addr,
-          m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(),
-          map.GetAddressByteSize(), write_error);
+      map.WriteScalarToMemory(load_addr, live_valobj_sp->GetValue().GetScalar(),
+                              map.GetAddressByteSize(), write_error);
 
       if (!write_error.Success()) {
         err = Status::FromErrorStringWithFormatv(
@@ -222,13 +224,15 @@ class EntityPersistentVariable : public Materializer::Entity {
       m_delegate->DidDematerialize(m_persistent_variable_sp);
     }
 
+    lldb::ValueObjectSP live_valobj_sp =
+        m_persistent_variable_sp->GetLiveObject();
     if ((m_persistent_variable_sp->m_flags &
          ExpressionVariable::EVIsLLDBAllocated) ||
         (m_persistent_variable_sp->m_flags &
          ExpressionVariable::EVIsProgramReference)) {
       if (m_persistent_variable_sp->m_flags &
               ExpressionVariable::EVIsProgramReference &&
-          !m_persistent_variable_sp->m_live_sp) {
+          !live_valobj_sp) {
         // If the reference comes from the program, then the
         // ClangExpressionVariable's live variable data hasn't been set up yet.
         // Do this now.
@@ -248,7 +252,7 @@ class EntityPersistentVariable : public Materializer::Entity {
 
         m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create(
             map.GetBestExecutionContextScope(),
-            m_persistent_variable_sp.get()->GetCompilerType(),
+            m_persistent_variable_sp->GetCompilerType(),
             m_persistent_variable_sp->GetName(), location, eAddressTypeLoad,
             llvm::expectedToOptional(m_persistent_variable_sp->GetByteSize())
                 .value_or(0));
@@ -270,19 +274,17 @@ class EntityPersistentVariable : public Materializer::Entity {
         }
       }
 
-      lldb::addr_t mem = m_persistent_variable_sp->m_live_sp->GetValue()
-                             .GetScalar()
-                             .ULongLong();
-
-      if (!m_persistent_variable_sp->m_live_sp) {
+      if (!live_valobj_sp) {
         err = Status::FromErrorStringWithFormat(
             "couldn't find the memory area used to store %s",
             m_persistent_variable_sp->GetName().GetCString());
         return;
       }
 
-      if (m_persistent_variable_sp->m_live_sp->GetValue()
-              .GetValueAddressType() != eAddressTypeLoad) {
+      lldb::addr_t mem = live_valobj_sp->GetValue().GetScalar().ULongLong();
+
+      if (live_valobj_sp->GetValue().GetValueAddressType() !=
+          eAddressTypeLoad) {
         err = Status::FromErrorStringWithFormat(
             "the address of the memory area for %s is in an incorrect format",
             m_persistent_variable_sp->GetName().GetCString());
@@ -319,7 +321,6 @@ class EntityPersistentVariable : public Materializer::Entity {
               read_error.AsCString());
           return;
         }
-
         m_persistent_variable_sp->m_flags &=
             ~ExpressionVariable::EVNeedsFreezeDry;
       }
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
index e2fb4a054daf3..d7b3fe0167299 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp
@@ -59,6 +59,6 @@ ClangExpressionVariable::ClangExpressionVariable(
 }
 
 TypeFromUser ClangExpressionVariable::GetTypeFromUser() {
-  TypeFromUser tfu(m_frozen_sp->GetCompilerType());
+  TypeFromUser tfu(GetValueObject()->GetCompilerType());
   return tfu;
 }
diff --git a/lldb/source/Target/ABI.cpp b/lldb/source/Target/ABI.cpp
index b7b45f9f4c44b..90d7430e53738 100644
--- a/lldb/source/Target/ABI.cpp
+++ b/lldb/source/Target/ABI.cpp
@@ -127,7 +127,7 @@ ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type,
           ExpressionVariable::EVNeedsAllocation;
       break;
     case Value::ValueType::LoadAddress:
-      expr_variable_sp->m_live_sp = live_valobj_sp;
+      expr_variable_sp->GetLiveObject() = live_valobj_sp;
       expr_variable_sp->m_flags |=
           ExpressionVariable::EVIsProgramReference;
       break;
diff --git a/lldb/test/API/functionalities/expr-result-var/Makefile b/lldb/test/API/functionalities/expr-result-var/Makefile
new file mode 100644
index 0000000000000..6c259307ef229
--- /dev/null
+++ b/lldb/test/API/functionalities/expr-result-var/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := two-bases.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/expr-result-var/TestCPPExprResult.py b/lldb/test/API/functionalities/expr-result-var/TestCPPExprResult.py
new file mode 100644
index 0000000000000..7bd4bb582a4a3
--- /dev/null
+++ b/lldb/test/API/functionalities/expr-result-var/TestCPPExprResult.py
@@ -0,0 +1,174 @@
+"""
+Test the reuse of  C++ result variables, particularly making sure
+that the dynamic typing is preserved.
+"""
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCPPResultVariables(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+    SHARED_BUILD_TESTCASE = False
+
+    def setUp(self):
+        TestBase.setUp(self)
+        self.main_source_file = lldb.SBFileSpec("two-bases.cpp")
+
+    def check_dereference(self, result_varname, frame, expr_options):
+        deref_expr = "*{0}".format(result_varname)
+        base_children = ValueCheck(
+            name="Base", value="", children=[ValueCheck(name="base_int", value="100")]
+        )
+        base_1_arr_children = [
+            ValueCheck(name="[0]", value="100"),
+            ValueCheck(name="[1]", value="101"),
+            ValueCheck(name="[2]", value="102"),
+            ValueCheck(name="[3]", value="103"),
+            ValueCheck(name="[4]", value="104"),
+            ValueCheck(name="[5]", value="105"),
+            ValueCheck(name="[6]", value="106"),
+            ValueCheck(name="[7]", value="107"),
+            ValueCheck(name="[8]", value="108"),
+            ValueCheck(name="[9]", value="109"),
+        ]
+        base_2_arr_children = [
+            ValueCheck(name="[0]", value="200"),
+            ValueCheck(name="[1]", value="201"),
+            ValueCheck(name="[2]", value="202"),
+            ValueCheck(name="[3]", value="203"),
+            ValueCheck(name="[4]", value="204"),
+            ValueCheck(name...
[truncated]

@jimingham

Copy link
Copy Markdown
Contributor Author

I also submitted:

#216226

to 23.x which fixes the flakey tests that were showing up in ObjC tests due to this patch.

@jimingham

Copy link
Copy Markdown
Contributor Author

The Linux test that failed is in one that ran no expressions...

@github-actions

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 34078 tests passed
  • 508 tests skipped
  • 1 test failed

Failed Tests

(click on a test name to see its output)

lldb-api

lldb-api.functionalities/gdb_remote_client/TestGdbClientModuleLoad.py
Script:
--
/usr/bin/python3 /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --env LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include --env LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --libcxx-include-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 --libcxx-include-target-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1 --libcxx-library-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu --triple x86_64-unknown-linux-gnu --build-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build --lldb-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/module-cache-lldb/lldb-api --clang-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/module-cache-clang/lldb-api --executable /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb --lldb-python-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/local/lib/python3.12/dist-packages --compiler /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang --dsymutil /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --lldb-obj-root /home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb --lldb-libs-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --cmake-build-type Release /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/gdb_remote_client -p TestGdbClientModuleLoad.py
--
Exit Code: 1

Command Output (stdout):
--
Skipping the following test categories: msvcstl, dsym, pdb, gmodules, debugserver, objc

--
Command Output (stderr):
--
PASS: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_android_app_process (TestGdbClientModuleLoad.TestGdbClientModuleLoad.test_android_app_process)

--- FileCheck trace (code=1) ---
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/FileCheck /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientModuleLoad.py -check-prefix=VDSO

FileCheck input:
[  0] 98FC07B8 0x0000000000ef0000 [vdso] (0xef0000)
[  1] 75B11BBB-EF8B-5645-B9B1-A7261EC8ABCF-05413284 0x0000000000ed8ed0 /home/gha/actions-runner/bin/Runner.Worker 


FileCheck output:

/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientModuleLoad.py:151:10: error: VDSO: expected string not found in input
 # VDSO: [ 0] {{.*}} 0x0000000000ee0000 {{.*}}module_load
         ^
<stdin>:1:1: note: scanning from here
[ 0] 98FC07B8 0x0000000000ef0000 [vdso] (0xef0000)
^

Input file: <stdin>
Check file: /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientModuleLoad.py

-dump-input=help explains the following input dump.

Input was:
<<<<<<
             1: [ 0] 98FC07B8 0x0000000000ef0000 [vdso] (0xef0000) 
check:151'0    {                                                     search range start (exclusive)
check:151'1                                                          error: no match found in search range
             2: [ 1] 75B11BBB-EF8B-5645-B9B1-A7261EC8ABCF-05413284 0x0000000000ed8ed0 /home/gha/actions-runner/bin/Runner.Worker  
check:151'2                                                                                                                       } search range end (exclusive)
>>>>>>



FAIL: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_vdso (TestGdbClientModuleLoad.TestGdbClientModuleLoad.test_vdso)
Log Files:
 - /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/functionalities/gdb_remote_client/TestGdbClientModuleLoad/Failure_test_vdso.log
======================================================================
FAIL: test_vdso (TestGdbClientModuleLoad.TestGdbClientModuleLoad.test_vdso)
   This test checks vdso loading in the situation where the process does
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestGdbClientModuleLoad.py", line 150, in test_vdso
    self.filecheck("image list", __file__, "-check-prefix=VDSO")
  File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 2789, in filecheck
    self.assertEqual(cmd_status, 0)
AssertionError: 1 != 0
Config=x86_64-/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang
----------------------------------------------------------------------
Ran 2 tests in 0.131s

FAILED (failures=1)

--

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@jimingham

Copy link
Copy Markdown
Contributor Author

Again, this patch only affects how ValueObjects that result from expressions are managed, and the test that's failing doesn't run any expressions (or use any ValueObjects really). I don't think that failure is related to this patch.

@dyung

dyung commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

I'm a bit confused here, in your original comment, you say that this is reverting the changes in e1af868, but that commit does not appear to be in the release branch. Am I missing something?

@jimingham

jimingham commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

I'm not sure how the release branch was made. Presumably it was made before the original patch and its revert happened, which is why they aren't on the release branch.

But this is cherry-picking the RESULT of the revert of that revert on main TO the release branch. Provided it cherry-picks cleanly I can't see that the other difference in history between the two branches matters?

@dyung

dyung commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

The release branch is created from an arbitrary commit when the branch is created. Anything after that point is not on the release branch unless it has been backported. For LLVM 23, the last commit that was selected was fb423ba. Any commits made to main after that point are not on the release branch by default.

From the git log e1af868 was committed on July 22, after we branched, so that is why it doesn't appear in the release/23.x branch.

Re-reading your most recent comment, this is a revert of the revert, so essentially you are trying to back-port the original change? If so, we do not normally accept backports of features to the release branch, only fixes for bugs and regressions.

Is this fixing a bug or a regression that is present on the release branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

3 participants