forked from OSchip/llvm-project
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> llvm-svn: 224559
This commit is contained in:
parent
9112607400
commit
3a95b5bce2
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue