summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2013-04-11 22:48:58 +0000
committerEnrico Granata <egranata@apple.com>2013-04-11 22:48:58 +0000
commit4873e52733b25c12a17be42f6fc14f3457f770d7 (patch)
treed0733e2111341457060b6cebe89a0f5f6c421b09 /lldb/source/Core
parent3342b9b2c98eb3d2f16dad26ccb9eef4efd9b70c (diff)
downloadbcm5719-llvm-4873e52733b25c12a17be42f6fc14f3457f770d7.tar.gz
bcm5719-llvm-4873e52733b25c12a17be42f6fc14f3457f770d7.zip
<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. llvm-svn: 179330
Diffstat (limited to 'lldb/source/Core')
-rw-r--r--lldb/source/Core/ValueObject.cpp65
-rw-r--r--lldb/source/Core/ValueObjectChild.cpp5
2 files changed, 69 insertions, 1 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 140c4b48b5e..dcc9e0e8265 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -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 (ExecutionContextScope *exe_scope,
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 (const char* name,
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;
+}
diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp
index 8aeb005512a..cf69ea5da68 100644
--- a/lldb/source/Core/ValueObjectChild.cpp
+++ b/lldb/source/Core/ValueObjectChild.cpp
@@ -229,5 +229,8 @@ ValueObjectChild::UpdateValue ()
bool
ValueObjectChild::IsInScope ()
{
- return m_parent->IsInScope ();
+ ValueObject* root(GetRoot());
+ if (root)
+ return root->IsInScope ();
+ return false;
}
OpenPOWER on IntegriCloud