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