Skip to content

Commit 5246825

Browse files
authored
Merge pull request swiftlang#1437 from jimingham/update-children-pointers
Fix Pavel's patch for ValueObjectVariables with complex DWARF express…
2 parents d6ebd84 + 473a5cb commit 5246825

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

lldb/include/lldb/Core/ValueObject.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,13 @@ class ValueObject : public UserID {
971971

972972
void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType);
973973

974+
void UpdateChildrenAddressType() {
975+
GetRoot()->DoUpdateChildrenAddressType(*this);
976+
}
977+
978+
protected:
979+
virtual void DoUpdateChildrenAddressType(ValueObject &valobj) { return; };
980+
974981
private:
975982
virtual CompilerType MaybeCalculateCompleteType();
976983

lldb/include/lldb/Core/ValueObjectVariable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class ValueObjectVariable : public ValueObject {
6767

6868
protected:
6969
bool UpdateValue() override;
70+
71+
void DoUpdateChildrenAddressType(ValueObject &valobj) override;
7072

7173
CompilerType GetCompilerTypeImpl() override;
7274

lldb/source/Core/ValueObjectVariable.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,64 @@ bool ValueObjectVariable::UpdateValue() {
331331
m_resolved_value.SetContext(Value::eContextTypeInvalid, nullptr);
332332
}
333333
}
334+
334335
return m_error.Success();
335336
}
336337

338+
void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) {
339+
Value::ValueType value_type = valobj.GetValue().GetValueType();
340+
ExecutionContext exe_ctx(GetExecutionContextRef());
341+
Process *process = exe_ctx.GetProcessPtr();
342+
const bool process_is_alive = process && process->IsAlive();
343+
const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo();
344+
const bool is_pointer_or_ref =
345+
(type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
346+
347+
switch (value_type) {
348+
case Value::eValueTypeFileAddress:
349+
// If this type is a pointer, then its children will be considered load
350+
// addresses if the pointer or reference is dereferenced, but only if
351+
// the process is alive.
352+
//
353+
// There could be global variables like in the following code:
354+
// struct LinkedListNode { Foo* foo; LinkedListNode* next; };
355+
// Foo g_foo1;
356+
// Foo g_foo2;
357+
// LinkedListNode g_second_node = { &g_foo2, NULL };
358+
// LinkedListNode g_first_node = { &g_foo1, &g_second_node };
359+
//
360+
// When we aren't running, we should be able to look at these variables
361+
// using the "target variable" command. Children of the "g_first_node"
362+
// always will be of the same address type as the parent. But children
363+
// of the "next" member of LinkedListNode will become load addresses if
364+
// we have a live process, or remain a file address if it was a file
365+
// address.
366+
if (process_is_alive && is_pointer_or_ref)
367+
valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
368+
else
369+
valobj.SetAddressTypeOfChildren(eAddressTypeFile);
370+
break;
371+
case Value::eValueTypeHostAddress:
372+
// Same as above for load addresses, except children of pointer or refs
373+
// are always load addresses. Host addresses are used to store freeze
374+
// dried variables. If this type is a struct, the entire struct
375+
// contents will be copied into the heap of the
376+
// LLDB process, but we do not currently follow any pointers.
377+
if (is_pointer_or_ref)
378+
valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
379+
else
380+
valobj.SetAddressTypeOfChildren(eAddressTypeHost);
381+
break;
382+
case Value::eValueTypeLoadAddress:
383+
case Value::eValueTypeScalar:
384+
case Value::eValueTypeVector:
385+
valobj.SetAddressTypeOfChildren(eAddressTypeLoad);
386+
break;
387+
}
388+
}
389+
390+
391+
337392
bool ValueObjectVariable::IsInScope() {
338393
const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
339394
if (exe_ctx_ref.HasFrameRef()) {

0 commit comments

Comments
 (0)