[Lldb-commits] [lldb] r224559 - Fixed an issue that could cause GetPointeeData() to fail when passing in a non-zero index.

Greg Clayton gclayton at apple.com
Thu Dec 18 17:28:42 PST 2014


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)





More information about the lldb-commits mailing list