Author: gclayton
Date: Thu Dec 18 19:28:42 2014
New Revision: 224559
URL: http://llvm.org/viewvc/llvm-project?rev=224559&view=rev
Log:
Fixed an issue that could cause GetPointeeData() to fail when passing in a
non-zero index.
The issue was we had a global variable that was a pointer, and the address type
of the children wasn't "load address" when it needed to be. Full details are in
the comments of the changes.
<rdar://problem/15107937>
Modified:
lldb/trunk/source/Core/ValueObjectVariable.cpp
Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=224559&r1=224558&r2=224559&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectVariable.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectVariable.cpp Thu Dec 18 19:28:42 2014
@@ -171,14 +171,44 @@ ValueObjectVariable::UpdateValue ()
m_value.SetClangType(clang_type);
Value::ValueType value_type = m_value.GetValueType();
-
+
+ Process *process = exe_ctx.GetProcessPtr();
+ const bool process_is_alive = process && process->IsAlive();
+ const uint32_t type_info = clang_type.GetTypeInfo();
+ const bool is_pointer_or_ref = (type_info & (lldb::eTypeIsPointer
| lldb::eTypeIsReference)) != 0;
+
switch (value_type)
{
case Value::eValueTypeFileAddress:
- SetAddressTypeOfChildren(eAddressTypeFile);
+ // If this type is a pointer, then its children will be
considered load addresses
+ // if the pointer or reference is dereferenced, but only
if the process is alive.
+ //
+ // There could be global variables like in the following
code:
+ // struct LinkedListNode { Foo* foo; LinkedListNode* next;
};
+ // Foo g_foo1;
+ // Foo g_foo2;
+ // LinkedListNode g_second_node = { &g_foo2, NULL };
+ // LinkedListNode g_first_node = { &g_foo1, &g_second_node
};
+ //
+ // When we aren't running, we should be able to look at
these variables using
+ // the "target variable" command. Children of the
"g_first_node" always will
+ // be of the same address type as the parent. But children
of the "next" member of
+ // LinkedListNode will become load addresses if we have a
live process, or remain
+ // what a file address if it what a file address.
+ if (process_is_alive && is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeFile);
break;
case Value::eValueTypeHostAddress:
- SetAddressTypeOfChildren(eAddressTypeHost);
+ // Same as above for load addresses, except children of
pointer or refs are always
+ // load addresses. Host addresses are used to store freeze
dried variables. If this
+ // type is a struct, the entire struct contents will be
copied into the heap of the
+ // LLDB process, but we do not currrently follow any
pointers.
+ if (is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeHost);
break;
case Value::eValueTypeLoadAddress:
case Value::eValueTypeScalar:
@@ -209,8 +239,7 @@ ValueObjectVariable::UpdateValue ()
// Make sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if
we can.
- Process *process = exe_ctx.GetProcessPtr();
- if (value_type == Value::eValueTypeFileAddress && process &&
process->IsAlive())
+ if (value_type == Value::eValueTypeFileAddress &&
process_is_alive)
{
lldb::addr_t file_addr =
m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (file_addr != LLDB_INVALID_ADDRESS)
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits