https://github.com/igorkudrin updated 
https://github.com/llvm/llvm-project/pull/145599

>From fac89bb1b51496761b156f22dcff85cbe86bf9d2 Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikud...@accesssoftek.com>
Date: Mon, 23 Jun 2025 23:39:52 -0700
Subject: [PATCH 1/2] [lldb] Fix evaluating expressions without JIT in an
 object context

If a server does not support allocating memory in an inferior process or
when debugging a core file, evaluating an expression in the context of a
value object results in an error:

```
error: <lldb wrapper prefix>:43:1: use of undeclared identifier '$__lldb_class'
   43 | $__lldb_class::$__lldb_expr(void *$__lldb_arg)
      | ^
```

Such expressions require a live address to be stored in the value
object. However, `EntityResultVariable::Dematerialize()` only sets
`ret->m_live_sp` if JIT is available, even if the address points to the
process memory and no custom allocations were made. Similarly,
`EntityPersistentVariable::Dematerialize()` tries to deallocate memory
based on the same check, resulting in an error if the memory was not
previously allocated in `EntityPersistentVariable::Materialize()`.

As an unintended bonus, the patch also fixes a FIXME case in
`TestCxxChar8_t.py`.
---
 lldb/source/Expression/Materializer.cpp       |  29 ++++-------
 .../postmortem/elf-core/expr/TestExpr.py      |  48 ++++++++++++++++++
 .../elf-core/expr/linux-x86_64.core           | Bin 0 -> 40960 bytes
 .../postmortem/elf-core/expr/linux-x86_64.out | Bin 0 -> 10816 bytes
 .../postmortem/elf-core/expr/main.cpp         |  15 ++++++
 .../API/lang/cpp/char8_t/TestCxxChar8_t.py    |   4 +-
 6 files changed, 73 insertions(+), 23 deletions(-)
 create mode 100644 
lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
 create mode 100644 
lldb/test/API/functionalities/postmortem/elf-core/expr/linux-x86_64.core
 create mode 100755 
lldb/test/API/functionalities/postmortem/elf-core/expr/linux-x86_64.out
 create mode 100644 
lldb/test/API/functionalities/postmortem/elf-core/expr/main.cpp

diff --git a/lldb/source/Expression/Materializer.cpp 
b/lldb/source/Expression/Materializer.cpp
index 79c804c6c4214..5f0dcd42289f6 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -329,22 +329,10 @@ class EntityPersistentVariable : public 
Materializer::Entity {
       return;
     }
 
-    lldb::ProcessSP process_sp =
-        map.GetBestExecutionContextScope()->CalculateProcess();
-    if (!process_sp || !process_sp->CanJIT()) {
-      // Allocations are not persistent so persistent variables cannot stay
-      // materialized.
-
-      m_persistent_variable_sp->m_flags |=
-          ExpressionVariable::EVNeedsAllocation;
-
-      DestroyAllocation(map, err);
-      if (!err.Success())
-        return;
-    } else if (m_persistent_variable_sp->m_flags &
-                   ExpressionVariable::EVNeedsAllocation &&
-               !(m_persistent_variable_sp->m_flags &
-                 ExpressionVariable::EVKeepInTarget)) {
+    if (m_persistent_variable_sp->m_flags &
+            ExpressionVariable::EVNeedsAllocation &&
+        !(m_persistent_variable_sp->m_flags &
+          ExpressionVariable::EVKeepInTarget)) {
       DestroyAllocation(map, err);
       if (!err.Success())
         return;
@@ -1086,9 +1074,8 @@ class EntityResultVariable : public Materializer::Entity {
       m_delegate->DidDematerialize(ret);
     }
 
-    bool can_persist =
-        (m_is_program_reference && process_sp && process_sp->CanJIT() &&
-         !(address >= frame_bottom && address < frame_top));
+    bool can_persist = m_is_program_reference &&
+                       !(address >= frame_bottom && address < frame_top);
 
     if (can_persist && m_keep_in_memory) {
       ret->m_live_sp = ValueObjectConstResult::Create(exe_scope, m_type, name,
@@ -1118,7 +1105,9 @@ class EntityResultVariable : public Materializer::Entity {
         map.Free(m_temporary_allocation, free_error);
       }
     } else {
-      ret->m_flags |= ExpressionVariable::EVIsLLDBAllocated;
+      ret->m_flags |= m_is_program_reference
+                          ? ExpressionVariable::EVIsProgramReference
+                          : ExpressionVariable::EVIsLLDBAllocated;
     }
 
     m_temporary_allocation = LLDB_INVALID_ADDRESS;
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py 
b/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
new file mode 100644
index 0000000000000..b397359e7a476
--- /dev/null
+++ b/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
@@ -0,0 +1,48 @@
+"""
+Test evaluating expressions when debugging core file.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+@skipIfLLVMTargetMissing("X86")
+class CoreExprTestCase(TestBase):
+    def test_result_var(self):
+        """Test that the result variable can be used in subsequent 
expressions."""
+
+        target = self.dbg.CreateTarget("linux-x86_64.out")
+        process = target.LoadCore("linux-x86_64.core")
+        self.assertTrue(process, PROCESS_IS_VALID)
+
+        self.expect_expr(
+            "outer",
+            result_type="Outer",
+            result_children=[ValueCheck(name="inner", type="Inner")],
+        )
+        self.expect_expr(
+            "$0.inner",
+            result_type="Inner",
+            result_children=[ValueCheck(name="val", type="int", value="5")],
+        )
+        self.expect_expr("$1.val", result_type="int", result_value="5")
+
+    def test_context_object(self):
+        """Tests expression evaluation in context of an object."""
+
+        target = self.dbg.CreateTarget("linux-x86_64.out")
+        process = target.LoadCore("linux-x86_64.core")
+        self.assertTrue(process, PROCESS_IS_VALID)
+
+        val_outer = self.expect_expr("outer", result_type="Outer")
+
+        val_inner = val_outer.EvaluateExpression("inner")
+        self.assertTrue(val_inner.IsValid())
+        self.assertEqual("Inner", val_inner.GetDisplayTypeName())
+
+        val_val = val_inner.EvaluateExpression("this->val")
+        self.assertTrue(val_val.IsValid())
+        self.assertEqual("int", val_val.GetDisplayTypeName())
+        self.assertEqual(val_val.GetValueAsSigned(), 5)
diff --git 
a/lldb/test/API/functionalities/postmortem/elf-core/expr/linux-x86_64.core 
b/lldb/test/API/functionalities/postmortem/elf-core/expr/linux-x86_64.core
new file mode 100644
index 
0000000000000000000000000000000000000000..3bd2916c64e9ff9facc4626ab53d785c47c6dcdf
GIT binary patch
literal 40960
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

literal 0
HcmV?d00001

diff --git 
a/lldb/test/API/functionalities/postmortem/elf-core/expr/linux-x86_64.out 
b/lldb/test/API/functionalities/postmortem/elf-core/expr/linux-x86_64.out
new file mode 100755
index 
0000000000000000000000000000000000000000..33e60f025d210798b0ca9425211c301eabe42da0
GIT binary patch
literal 10816
zcmeHN&u<$=6n?YowViC7I87l*1I?zbQA(xF4^l{JXk8MwZbbtLN)@4&tsQR~OR*i<
z>nKo4i-JH=K#;$H9yoA@OSy0<qLnysgx;xCBm_aUQV>Ytz1bOOF`*O*^)w^BdGCGi
zdo#PAXKh8<%c&QRYm9*$8XN(h#giQJXMp4rl7TS{gMo7#S~xefRl=y&!O>~4wDj1-
z2f+qKA_uXb^oyJYAid;KAK%Xs1S{zW!e14z^s?`z+g|Q|efvb8^qh;>1onkR?LnNp
zod@A6j#5A=pcGIFC<T-PN&%&SQa~x76i^B%1s;|HQ|Xo4>E$2e>Gv=F@df=serFd>
z=^Lqax`Om-YW*wdOD}&JKX<*Qdkmn)U%9lgQoWmAy|l4fy?f^oB6HTP-O~Lw^}-fk
za#I_tr|+&r&t2zrH7Ny@0!jg;fKosypcGIFC<T-PN&%&SQa~y2kQ88D`eFK?w@&-5
zZ*C^h^`k$J{yh3C=xOZq9kACYfi1;ZS5qYVA^tP|F~rHP{k*w(fH=pR<L_vrvG6Ps
zL~R89O|16>>u0y>XA%Dn>yHNO6MlUvTP=E3Yi2%EykIT5<x0L(v<42@1NMN`J5c4-
zfj0+-?EWEpa6jC`B@AG+GrpS8BO**RLinIs6PnhKldgwZ$cTm@Y=mB>aumW*h(s<@
zSSA2MMkEBxFnFdzI09OP-bxT<9XmB@)rN3t01|<nX#lfPTYIAkVuWJ25QAo}kI6^|
zcIGp}M{#P>)|Q%o!XT!tc?LxIKBh)uurs%CHnWoTYmKFG7T=O@4y=_W5^aW_D7VMk
zyArKzYHy|8YsbrKfs<``qx(Ql95GE3Z>WtuZR!creAYaSsS(4<$u>%cF%8>HPf#+_
zd9)KCVqp6a22l#|25r{bwIiJD@JU2z90E<G#4sfz*H%oNK%mLsb$^+dpU?(GhL6z<
zRQ(zBjIrOFW8~;94>SzADFmH$Yc0lZ7NO+H{mVBx^BYV0#fGQueVrHy;Z<q!y%F7H
zMnmKBw?=5$Xb7J&SlE0{3*$<h)gMpN3eaKfYK+>(&hUs~nbTYK^P=8nbTod?%ezfm
z)3E(Np2I>WU$kcy7NE~7Ec6Y)%v`1n`C`#6!(wJ0BM(mU?8T~wm{ajGWe=QJ#t(8}
zbTF0Y87J|q#EIEbsQ}(wzQP|m5>DQ@yft|XV&mF{(0L+0>4{q41AjngJvyGVB(LCv
zqYrHu?I_w9+9|Ygv`MsSv{%twv<li=Xz!xEhxU)d-|m;q?Fb?GJKo5N__SKdzqIVZ
zYzJMu_=NbggxKR~ar*Y^Phzw+_G7pmP7nQd_(8<?;QCU=9<dZXp@d6W`F9l6YQj3s
ziSa2Xm3EF#9y^_K(qoh0IN3@?ex`0N<7L2ci@E!LzF=2gD|neKdavyJIT?BGk_Was
z=ggKf1=pF&mA5jmXG(>FiwDZix!LLkCtsW`$vBhEmfb~}&F71*jB#lhW^%Ni-%J#|
z@LFCjUYO5Uyo#)2$tlgwR$PSsm(hi*&>5+{V<kRc`Q8?N(*{TV`&INgQ9qs-f5>xV
z`RP6ZOGigPIOxD*|AOrA75%-I&sqwSG3LK40qhXQv_GAz;J9k}8Lb~2#HAtq^MRNb
z#Pp5j2fqbDjAfsM>EW!$sCKi*XI%4LZLa6iZ*M(D<STppmQQ?Fo9nrASRt(b{(JZO
zEo-$-Kal;>(=n29kovjkw}Rj{+{*&1-~X2AuRkwxFX=znW=-1i2hmUe4G9j}C$Wz(
zsK=;=zqfqQmuPU*b19c+FUU)a{&fL1qo=bg&tHeY8_??_4!YrlpG^cojO+JrMQpqN
L7196czx4kJjnh(U

literal 0
HcmV?d00001

diff --git a/lldb/test/API/functionalities/postmortem/elf-core/expr/main.cpp 
b/lldb/test/API/functionalities/postmortem/elf-core/expr/main.cpp
new file mode 100644
index 0000000000000..32a9c63e9b716
--- /dev/null
+++ b/lldb/test/API/functionalities/postmortem/elf-core/expr/main.cpp
@@ -0,0 +1,15 @@
+struct Inner {
+  Inner(int val) : val(val) {}
+  int val;
+};
+
+struct Outer {
+  Outer(int val) : inner(val) {}
+  Inner inner;
+};
+
+extern "C" void _start(void) {
+  Outer outer(5);
+  char *boom = (char *)0;
+  *boom = 47;
+}
diff --git a/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py 
b/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py
index 4eb5351eefc82..08f09b317b217 100644
--- a/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py
+++ b/lldb/test/API/lang/cpp/char8_t/TestCxxChar8_t.py
@@ -24,9 +24,7 @@ def test_without_process(self):
 
         self.expect_expr("a", result_type="char8_t", result_summary="0x61 
u8'a'")
         self.expect_expr("ab", result_type="const char8_t *", 
result_summary='u8"你好"')
-
-        # FIXME: This should work too.
-        self.expect("expr abc", substrs=['u8"你好"'], matching=False)
+        self.expect_expr("abc", result_type="char8_t[9]", 
result_summary='u8"你好"')
 
     @skipIf(compiler="clang", compiler_version=["<", "7.0"])
     def test_with_process(self):

>From 699cf516bab5a647f5dfeda7fd3b39f441f83768 Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikud...@accesssoftek.com>
Date: Tue, 24 Jun 2025 23:40:32 -0700
Subject: [PATCH 2/2] fixup! fix user-defined persistent variables

---
 lldb/include/lldb/Expression/IRMemoryMap.h    |  6 ++++-
 lldb/source/Expression/IRMemoryMap.cpp        |  6 ++++-
 lldb/source/Expression/Materializer.cpp       | 24 +++++++++++++------
 .../postmortem/elf-core/expr/TestExpr.py      | 22 ++++++++++-------
 4 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/lldb/include/lldb/Expression/IRMemoryMap.h 
b/lldb/include/lldb/Expression/IRMemoryMap.h
index abec5442793c6..5b33dd2f84f95 100644
--- a/lldb/include/lldb/Expression/IRMemoryMap.h
+++ b/lldb/include/lldb/Expression/IRMemoryMap.h
@@ -50,8 +50,12 @@ class IRMemoryMap {
                                  ///only in the process.
   };
 
+  // If 'policy' is 'eAllocationPolicyMirror' but it is impossible to allocate
+  // memory in the process, 'eAllocationPolicyHostOnly' will be used instead.
+  // The actual policy is returned via 'used_policy'.
   lldb::addr_t Malloc(size_t size, uint8_t alignment, uint32_t permissions,
-                      AllocationPolicy policy, bool zero_memory, Status 
&error);
+                      AllocationPolicy policy, bool zero_memory, Status &error,
+                      AllocationPolicy *used_policy = nullptr);
   void Leak(lldb::addr_t process_address, Status &error);
   void Free(lldb::addr_t process_address, Status &error);
 
diff --git a/lldb/source/Expression/IRMemoryMap.cpp 
b/lldb/source/Expression/IRMemoryMap.cpp
index 65b5d11413c85..813b516443d13 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -321,7 +321,8 @@ IRMemoryMap::Allocation::Allocation(lldb::addr_t 
process_alloc,
 
 lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment,
                                  uint32_t permissions, AllocationPolicy policy,
-                                 bool zero_memory, Status &error) {
+                                 bool zero_memory, Status &error,
+                                 AllocationPolicy *used_policy) {
   lldb_private::Log *log(GetLog(LLDBLog::Expressions));
   error.Clear();
 
@@ -455,6 +456,9 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t 
alignment,
               (uint64_t)permissions, policy_string, aligned_address);
   }
 
+  if (used_policy)
+    *used_policy = policy;
+
   return aligned_address;
 }
 
diff --git a/lldb/source/Expression/Materializer.cpp 
b/lldb/source/Expression/Materializer.cpp
index 5f0dcd42289f6..5ea273f2e54d2 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -76,12 +76,14 @@ class EntityPersistentVariable : public 
Materializer::Entity {
 
     Status allocate_error;
     const bool zero_memory = false;
+    IRMemoryMap::AllocationPolicy used_policy;
 
     lldb::addr_t mem = map.Malloc(
         llvm::expectedToOptional(m_persistent_variable_sp->GetByteSize())
             .value_or(0),
         8, lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-        IRMemoryMap::eAllocationPolicyMirror, zero_memory, allocate_error);
+        IRMemoryMap::eAllocationPolicyMirror, zero_memory, allocate_error,
+        &used_policy);
 
     if (!allocate_error.Success()) {
       err = Status::FromErrorStringWithFormat(
@@ -103,14 +105,22 @@ class EntityPersistentVariable : public 
Materializer::Entity {
         m_persistent_variable_sp->GetName(), mem, eAddressTypeLoad,
         map.GetAddressByteSize());
 
-    // Clear the flag if the variable will never be deallocated.
-
     if (m_persistent_variable_sp->m_flags &
         ExpressionVariable::EVKeepInTarget) {
-      Status leak_error;
-      map.Leak(mem, leak_error);
-      m_persistent_variable_sp->m_flags &=
-          ~ExpressionVariable::EVNeedsAllocation;
+      if (used_policy == IRMemoryMap::eAllocationPolicyMirror) {
+        // Clear the flag if the variable will never be deallocated.
+        Status leak_error;
+        map.Leak(mem, leak_error);
+        m_persistent_variable_sp->m_flags &=
+            ~ExpressionVariable::EVNeedsAllocation;
+      } else {
+        // If the variable cannot be kept in target, clear this flag...
+        m_persistent_variable_sp->m_flags &=
+            ~ExpressionVariable::EVKeepInTarget;
+        // ...and set the flag to copy the value during dematerialization.
+        m_persistent_variable_sp->m_flags |=
+            ExpressionVariable::EVNeedsFreezeDry;
+      }
     }
 
     // Write the contents of the variable to the area.
diff --git a/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py 
b/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
index b397359e7a476..dd03a0cc836a7 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/expr/TestExpr.py
@@ -10,13 +10,15 @@
 
 @skipIfLLVMTargetMissing("X86")
 class CoreExprTestCase(TestBase):
+    def setUp(self):
+        TestBase.setUp(self)
+        self.target = self.dbg.CreateTarget("linux-x86_64.out")
+        self.process = self.target.LoadCore("linux-x86_64.core")
+        self.assertTrue(self.process, PROCESS_IS_VALID)
+
     def test_result_var(self):
         """Test that the result variable can be used in subsequent 
expressions."""
 
-        target = self.dbg.CreateTarget("linux-x86_64.out")
-        process = target.LoadCore("linux-x86_64.core")
-        self.assertTrue(process, PROCESS_IS_VALID)
-
         self.expect_expr(
             "outer",
             result_type="Outer",
@@ -29,12 +31,14 @@ def test_result_var(self):
         )
         self.expect_expr("$1.val", result_type="int", result_value="5")
 
-    def test_context_object(self):
-        """Tests expression evaluation in context of an object."""
+    def test_persist_var(self):
+        """Test that user-defined variables can be used in subsequent 
expressions."""
 
-        target = self.dbg.CreateTarget("linux-x86_64.out")
-        process = target.LoadCore("linux-x86_64.core")
-        self.assertTrue(process, PROCESS_IS_VALID)
+        self.target.EvaluateExpression("int $my_int = 5")
+        self.expect_expr("$my_int * 2", result_type="int", result_value="10")
+
+    def test_context_object(self):
+        """Test expression evaluation in context of an object."""
 
         val_outer = self.expect_expr("outer", result_type="Outer")
 

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to