Skip to content

Commit b9dc2c1

Browse files
committed
Don't produce a dynamic value if there was an error creating it.
We used to make a dynamic value that "pretended to be its parent" but that's hard for some of the more complex ValueObject types, and it's better in this case just to return no dynamic value. Differential Revision: https://reviews.llvm.org/D145629 (cherry picked from commit e1462d1)
1 parent 6b16dea commit b9dc2c1

File tree

7 files changed

+62
-9
lines changed

7 files changed

+62
-9
lines changed

lldb/source/Core/ValueObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1938,7 +1938,7 @@ ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
19381938
if (!IsDynamic() && m_dynamic_value == nullptr) {
19391939
CalculateDynamicValue(use_dynamic);
19401940
}
1941-
if (m_dynamic_value)
1941+
if (m_dynamic_value && m_dynamic_value->GetError().Success())
19421942
return m_dynamic_value->GetSP();
19431943
else
19441944
return ValueObjectSP();

lldb/source/Core/ValueObjectConstResult.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ ValueObjectConstResult::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
289289
if (process && process->IsPossibleDynamicValue(*this))
290290
m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
291291
}
292-
if (m_dynamic_value)
292+
if (m_dynamic_value && m_dynamic_value->GetError().Success())
293293
return m_dynamic_value->GetSP();
294294
}
295295
return ValueObjectSP();

lldb/source/Core/ValueObjectDynamicValue.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,17 +233,19 @@ bool ValueObjectDynamicValue::UpdateValue() {
233233
m_type_impl.Clear();
234234
}
235235

236-
// If we don't have a dynamic type, then make ourselves just a echo of our
237-
// parent. Or we could return false, and make ourselves an echo of our
238-
// parent?
236+
// If we don't have a dynamic type, set ourselves to be invalid and return
237+
// false. We used to try to produce a dynamic ValueObject that behaved "like"
238+
// its parent, but that failed for ValueObjectConstResult, which is too
239+
// complex a beast to try to emulate. If we return an invalid ValueObject,
240+
// clients will end up getting the static value instead, which behaves
241+
// correctly.
239242
if (!found_dynamic_type) {
240243
if (m_dynamic_type_info)
241244
SetValueDidChange(true);
242245
ClearDynamicTypeInformation();
243246
m_dynamic_type_info.Clear();
244-
m_value = m_parent->GetValue();
245-
m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
246-
return m_error.Success();
247+
m_error.SetErrorString("no dynamic type found");
248+
return false;
247249
}
248250

249251
Value old_value(m_value);

lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,11 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread(
583583
ValueObjectSP exception = ValueObject::CreateValueObjectFromData(
584584
"exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx,
585585
voidstar);
586-
exception = exception->GetDynamicValue(eDynamicDontRunTarget);
586+
ValueObjectSP dyn_exception
587+
= exception->GetDynamicValue(eDynamicDontRunTarget);
588+
// If we succeed in making a dynamic value, return that:
589+
if (dyn_exception)
590+
return dyn_exception;
587591

588592
return exception;
589593
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
C_SOURCES := main.c
2+
3+
include Makefile.rules
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
class ValueAPIVoidStarTestCase(TestBase):
7+
8+
def test(self):
9+
self.build()
10+
11+
target, process, thread, _ = lldbutil.run_to_source_breakpoint(self,
12+
"Break at this line",
13+
lldb.SBFileSpec("main.c"))
14+
frame = thread.GetFrameAtIndex(0)
15+
16+
# Verify that the expression result for a void * behaves the same way as the
17+
# variable value.
18+
19+
var_val = frame.FindVariable("void_ptr")
20+
self.assertSuccess(var_val.GetError(), "Var version made correctly")
21+
22+
expr_val = frame.EvaluateExpression("void_ptr")
23+
self.assertSuccess(expr_val.GetError(), "Expr version succeeds")
24+
25+
# The pointer values should be equal:
26+
self.assertEqual(var_val.unsigned, expr_val.unsigned, "Values are equal")
27+
28+
# Both versions should have valid AddressOf, and they should be the same.
29+
30+
val_addr_of = var_val.AddressOf()
31+
self.assertNotEqual(val_addr_of, lldb.LLDB_INVALID_ADDRESS, "Var addr of right")
32+
33+
expr_addr_of = expr_val.AddressOf()
34+
self.assertNotEqual(expr_addr_of, lldb.LLDB_INVALID_ADDRESS, "Expr addr of right")
35+
36+
# The AddressOf values should also be equal.
37+
self.assertEqual(expr_addr_of.unsigned, val_addr_of.unsigned, "Addr of equal")
38+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int main (int argc, char const *argv[]) {
2+
char *char_ptr = "Some pointer here";
3+
void *void_ptr = &char_ptr;
4+
5+
return 0; // Break at this line
6+
}

0 commit comments

Comments
 (0)