summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2012-01-10 03:58:23 +0000
committerJim Ingham <jingham@apple.com>2012-01-10 03:58:23 +0000
commitf714d3d7f217d06ebddd7ab6c0fc0019e59d5ea7 (patch)
tree34934f0dcdf055b3410920f7d63398402a7e9765
parent9163e360d680a54b39c3205f99ef769f474e900d (diff)
downloadbcm5719-llvm-f714d3d7f217d06ebddd7ab6c0fc0019e59d5ea7.tar.gz
bcm5719-llvm-f714d3d7f217d06ebddd7ab6c0fc0019e59d5ea7.zip
As we are grubbing through memory chasing down the hierarchy of an ObjC object, protect against the possibility that that object might be just random memory with loops.
llvm-svn: 147838
-rw-r--r--lldb/include/lldb/Core/FormatNavigator.h32
1 files changed, 27 insertions, 5 deletions
diff --git a/lldb/include/lldb/Core/FormatNavigator.h b/lldb/include/lldb/Core/FormatNavigator.h
index b253e053683..437cecadef1 100644
--- a/lldb/include/lldb/Core/FormatNavigator.h
+++ b/lldb/include/lldb/Core/FormatNavigator.h
@@ -375,8 +375,11 @@ protected:
return Get_Impl(type, entry, Types<KeyType,ValueType>());
}
+ #define LLDB_MAX_REASONABLE_OBJC_CLASS_DEPTH 100
+
bool Get_ObjC(ValueObject& valobj,
ObjCLanguageRuntime::ObjCISA isa,
+ std::set<ObjCLanguageRuntime::ObjCISA> &found_values,
MapValueType& entry,
uint32_t& reason)
{
@@ -397,6 +400,7 @@ protected:
log->Printf("invalid ISA, bailing out");
return false;
}
+
ConstString name = runtime->GetActualTypeName(isa);
if (log)
log->Printf("looking for formatter for %s", name.GetCString());
@@ -415,13 +419,29 @@ protected:
log->Printf("invalid parent ISA, bailing out");
return false;
}
- if (parent == isa)
+
+ // Put the isa value in our map. Then check the new_value, if it was already there, we've got a
+ // loop in the inheritance hierarchy, and should bag out.
+ std::pair<std::set<ObjCLanguageRuntime::ObjCISA>::iterator, bool> new_value = found_values.insert (isa);
+ if (new_value.second == false)
+ {
+ //Our value already existed in the map.
+ if (log)
+ log->Printf ("ISA: 0x%llx already found in inheritance chain.", isa);
+ return false;
+ }
+
+ if (found_values.size() > LLDB_MAX_REASONABLE_OBJC_CLASS_DEPTH)
{
+ // ObjC hierarchies are usually pretty shallow, if we've gone this far, we are probably chasing
+ // uninitialized memory.
if (log)
- log->Printf("parent-child loop, bailing out");
+ log->Printf("Parent-child depth of %d, we are probably off in the weeds, bailing out.",
+ LLDB_MAX_REASONABLE_OBJC_CLASS_DEPTH);
return false;
}
- if (Get_ObjC(valobj, parent, entry, reason))
+
+ if (Get_ObjC(valobj, parent, found_values, entry, reason))
{
reason |= lldb_private::eFormatterChoiceCriterionNavigatedBaseClasses;
return true;
@@ -512,7 +532,8 @@ protected:
}
else
{
- if (Get_ObjC(valobj, runtime->GetISA(valobj), entry, reason))
+ std::set<ObjCLanguageRuntime::ObjCISA> found_values;
+ if (Get_ObjC(valobj, runtime->GetISA(valobj), found_values, entry, reason))
{
reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCHierarchy;
return true;
@@ -555,7 +576,8 @@ protected:
}
else
{
- if (Get_ObjC(valobj, runtime->GetISA(valobj), entry, reason))
+ std::set<ObjCLanguageRuntime::ObjCISA> found_values;
+ if (Get_ObjC(valobj, runtime->GetISA(valobj), found_values, entry, reason))
{
reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCHierarchy;
return true;
OpenPOWER on IntegriCloud