[Lldb-commits] [lldb] r179330 - <rdar://problem/13623698>

Enrico Granata egranata at apple.com
Thu Apr 11 15:48:58 PDT 2013


Author: enrico
Date: Thu Apr 11 17:48:58 2013
New Revision: 179330

URL: http://llvm.org/viewvc/llvm-project?rev=179330&view=rev
Log:
<rdar://problem/13623698>

This patch fixes the issue that we were using the C stack as a measure of depth of ValueObject hierarchies, in the sense that we were assuming that recursive ValueObject operations would never be deeper than the stack allows.
This assumption is easy to prove wrong, however.
For instance, after ~10k runs through this loop:
struct node
{
	int value;
	node* child;
	node (int x)
	{
		value = x;
		child = nullptr;
	}
};

int main ()
{
	node root(1);
	node* ptr = &root;
	int j = 2;
	while (1)
	{
		ptr->child = new node(j++);
		ptr = ptr->child;
	}
	return 0;
}

the deepmost child object will be deeper than the stack on most architectures, and we would be unable to display it

This checkin fixes the issue by introducing a notion of root of ValueObject hierarchies.
In a couple cases, we have to use an iterative algorithm instead of going to the root because we want to allow deeper customizations (e.g. formats, dynamic values).
While the patch passes our test suite without regressions, it is a good idea to keep eyes open for any unexpected behavior (recursion can be subtle..)
Also, I am hesitant to introduce a test case since failing at this will not just be marked as an "F", but most definitely crash LLDB.


Modified:
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectChild.cpp

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=179330&r1=179329&r2=179330&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Thu Apr 11 17:48:58 2013
@@ -738,12 +738,10 @@ public:
     // value is from an executable file and might have its data in
     // sections of the file. This can be used for variables.
     virtual lldb::ModuleSP
-    GetModule()
-    {
-        if (m_parent)
-            return m_parent->GetModule();
-        return lldb::ModuleSP();
-    }
+    GetModule();
+    
+    virtual ValueObject*
+    GetRoot ();
     
     virtual bool
     GetDeclaration (Declaration &decl);
@@ -876,14 +874,8 @@ public:
     virtual lldb::ValueObjectSP
     GetDynamicValue (lldb::DynamicValueType valueType);
     
-    virtual lldb::DynamicValueType
-    GetDynamicValueType ()
-    {
-        if (m_parent)
-            return m_parent->GetDynamicValueType ();
-        else
-            return lldb::eNoDynamicValues;
-    }
+    lldb::DynamicValueType
+    GetDynamicValueType ();
     
     virtual lldb::ValueObjectSP
     GetStaticValue ();
@@ -1020,12 +1012,7 @@ public:
     }
 
     lldb::Format
-    GetFormat () const
-    {
-        if (m_parent && m_format == lldb::eFormatDefault)
-            return m_parent->GetFormat();
-        return m_format;
-    }
+    GetFormat () const;
     
     void
     SetFormat (lldb::Format format)
@@ -1104,15 +1091,7 @@ public:
     }
     
     AddressType
-    GetAddressTypeOfChildren()
-    {
-        if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid)
-        {
-            if (m_parent)
-                return m_parent->GetAddressTypeOfChildren();
-        }
-        return m_address_type_of_ptr_or_ref_children;
-    }
+    GetAddressTypeOfChildren();
     
     void
     SetHasCompleteType()
@@ -1213,6 +1192,7 @@ protected:
     // Classes that inherit from ValueObject can see and modify these
     //------------------------------------------------------------------
     ValueObject  *      m_parent;       // The parent value object, or NULL if this has no parent
+    ValueObject  *      m_root;         // The root of the hierarchy for this ValueObject (or NULL if never calculated)
     EvaluationPoint     m_update_point; // Stores both the stop id and the full context at which this value was last 
                                         // updated.  When we are asked to update the value object, we check whether
                                         // the context & stop id are the same before updating.
@@ -1300,6 +1280,18 @@ protected:
     virtual void
     CalculateDynamicValue (lldb::DynamicValueType use_dynamic);
     
+    virtual lldb::DynamicValueType
+    GetDynamicValueTypeImpl ()
+    {
+        return lldb::eNoDynamicValues;
+    }
+    
+    virtual bool
+    HasDynamicValueTypeInfo ()
+    {
+        return false;
+    }
+    
     virtual void
     CalculateSyntheticValue (bool use_synthetic = true);
     

Modified: lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h?rev=179330&r1=179329&r2=179330&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h Thu Apr 11 17:48:58 2013
@@ -90,15 +90,21 @@ public:
     virtual bool
     SetValueFromCString (const char *value_str, Error& error);
     
+protected:
+    virtual bool
+    UpdateValue ();
+    
     virtual lldb::DynamicValueType
-    GetDynamicValueType ()
+    GetDynamicValueTypeImpl ()
     {
         return m_use_dynamic;
     }
     
-protected:
     virtual bool
-    UpdateValue ();
+    HasDynamicValueTypeInfo ()
+    {
+        return true;
+    }
     
     virtual clang::ASTContext *
     GetClangASTImpl ();

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=179330&r1=179329&r2=179330&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Thu Apr 11 17:48:58 2013
@@ -64,6 +64,7 @@ static user_id_t g_value_obj_uid = 0;
 ValueObject::ValueObject (ValueObject &parent) :
     UserID (++g_value_obj_uid), // Unique identifier for every value object
     m_parent (&parent),
+    m_root (NULL),
     m_update_point (parent.GetUpdatePoint ()),
     m_name (),
     m_data (),
@@ -108,6 +109,7 @@ ValueObject::ValueObject (ExecutionConte
                           AddressType child_ptr_or_ref_addr_type) :
     UserID (++g_value_obj_uid), // Unique identifier for every value object
     m_parent (NULL),
+    m_root (NULL),
     m_update_point (exe_scope),
     m_name (),
     m_data (),
@@ -4150,3 +4152,66 @@ ValueObject::CreateValueObjectFromData (
         new_value_sp->SetName(ConstString(name));
     return new_value_sp;
 }
+
+ModuleSP
+ValueObject::GetModule ()
+{
+    ValueObject* root(GetRoot());
+    if (root != this)
+        return root->GetModule();
+    return lldb::ModuleSP();
+}
+
+ValueObject*
+ValueObject::GetRoot ()
+{
+    if (m_root)
+        return m_root;
+    ValueObject* parent = m_parent;
+    if (!parent)
+        return (m_root = this);
+    while (parent->m_parent)
+    {
+        if (parent->m_root)
+            return (m_root = parent->m_root);
+        parent = parent->m_parent;
+    }
+    return (m_root = parent);
+}
+
+AddressType
+ValueObject::GetAddressTypeOfChildren()
+{
+    if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid)
+    {
+        ValueObject* root(GetRoot());
+        if (root != this)
+            return root->GetAddressTypeOfChildren();
+    }
+    return m_address_type_of_ptr_or_ref_children;
+}
+
+lldb::DynamicValueType
+ValueObject::GetDynamicValueType ()
+{
+    ValueObject* with_dv_info = this;
+    while (with_dv_info)
+    {
+        if (with_dv_info->HasDynamicValueTypeInfo())
+            return with_dv_info->GetDynamicValueTypeImpl();
+        with_dv_info = with_dv_info->m_parent;
+    }
+    return lldb::eNoDynamicValues;
+}
+lldb::Format
+ValueObject::GetFormat () const
+{
+    const ValueObject* with_fmt_info = this;
+    while (with_fmt_info)
+    {
+        if (with_fmt_info->m_format != lldb::eFormatDefault)
+            return with_fmt_info->m_format;
+        with_fmt_info = with_fmt_info->m_parent;
+    }
+    return m_format;
+}

Modified: lldb/trunk/source/Core/ValueObjectChild.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectChild.cpp?rev=179330&r1=179329&r2=179330&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectChild.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectChild.cpp Thu Apr 11 17:48:58 2013
@@ -229,5 +229,8 @@ ValueObjectChild::UpdateValue ()
 bool
 ValueObjectChild::IsInScope ()
 {
-    return m_parent->IsInScope ();
+    ValueObject* root(GetRoot());
+    if (root)
+        return root->IsInScope ();
+    return false;
 }





More information about the lldb-commits mailing list