aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Expression/Materializer.cpp
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin@accesssoftek.com>2025-06-27 14:30:24 -0700
committerGitHub <noreply@github.com>2025-06-27 14:30:24 -0700
commit442f99d7698a4ca87ebb16cb22df610c45d4698a (patch)
tree6cd1bf747cd0a88ab49167103bbcb44c4f544ace /lldb/source/Expression/Materializer.cpp
parent9f5061d4f00456d882db9eb606f4a82b2c40e7a8 (diff)
downloadllvm-442f99d7698a4ca87ebb16cb22df610c45d4698a.zip
llvm-442f99d7698a4ca87ebb16cb22df610c45d4698a.tar.gz
llvm-442f99d7698a4ca87ebb16cb22df610c45d4698a.tar.bz2
[lldb] Fix evaluating expressions without JIT in an object context (#145599)
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`.
Diffstat (limited to 'lldb/source/Expression/Materializer.cpp')
-rw-r--r--lldb/source/Expression/Materializer.cpp52
1 files changed, 25 insertions, 27 deletions
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 96add56..17ea159 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -75,11 +75,12 @@ public:
// contents.
const bool zero_memory = false;
+ IRMemoryMap::AllocationPolicy used_policy;
auto address_or_error = map.Malloc(
llvm::expectedToOptional(m_persistent_variable_sp->GetByteSize())
.value_or(0),
8, lldb::ePermissionsReadable | lldb::ePermissionsWritable,
- IRMemoryMap::eAllocationPolicyMirror, zero_memory);
+ IRMemoryMap::eAllocationPolicyMirror, zero_memory, &used_policy);
if (!address_or_error) {
err = Status::FromErrorStringWithFormat(
"couldn't allocate a memory area to store %s: %s",
@@ -101,14 +102,22 @@ public:
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.
@@ -327,22 +336,10 @@ public:
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;
@@ -1082,9 +1079,8 @@ public:
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,
@@ -1114,7 +1110,9 @@ public:
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;