Check all pointers to PropLists in c4values in debug engines

This can find some refcounting errors by verifying that the proplist did
not get deleted before it is used.
floating-point
Günther Brammer 2011-02-06 22:30:31 +01:00
parent 75dc49e746
commit 39276c6fd1
3 changed files with 24 additions and 1 deletions

View File

@ -158,12 +158,19 @@ C4PropListNumbered::~C4PropListNumbered()
Log("removing numbered proplist without number");
}
#ifdef _DEBUG
C4Set<C4PropList *> C4PropList::PropLists;
#endif
C4PropList::C4PropList(C4PropList * prototype):
Status(1),
FirstRef(NULL), prototype(prototype), constant(false)
{
if (prototype)
SetProperty(P_Prototype, C4VPropList(prototype));
#ifdef _DEBUG
PropLists.Add(this);
#endif
}
void C4PropList::DenumeratePointers()
@ -189,6 +196,10 @@ C4PropList::~C4PropList()
FirstRef = FirstRef->NextRef;
ref->NextRef = NULL;
}
#ifdef _DEBUG
assert(PropLists.Has(this));
PropLists.Remove(this);
#endif
assert(!C4PropListNumbered::CheckPropList(this));
}
@ -485,3 +496,9 @@ bool C4Set<C4PropListNumbered *>::Equals<C4PropList *>(C4PropListNumbered * a, C
{
return a == b;
}
template<> template<>
unsigned int C4Set<C4PropList *>::Hash<C4PropList *>(C4PropList * e)
{
return C4Set<C4PropListNumbered *>::Hash(static_cast<int>(reinterpret_cast<intptr_t>(e)));
}

View File

@ -102,6 +102,9 @@ public:
void AppendDataString(StdStrBuf * out, const char * delim);
bool operator==(const C4PropList &b) const;
#ifdef _DEBUG
static C4Set<C4PropList *> PropLists;
#endif
protected:
C4PropList(C4PropList * prototype = 0);

View File

@ -239,11 +239,14 @@ ALWAYS_INLINE void C4Value::AddDataRef()
case C4V_Array: Data.Array->IncRef(); break;
case C4V_String: Data.Str->IncRef(); break;
case C4V_C4Object:
case C4V_PropList:
#ifdef _DEBUG
// check if the object actually exists
if (!C4PropListNumbered::CheckPropList(Data.PropList))
{ LogF("Warning: using wild object ptr %p!", static_cast<void*>(Data.Obj)); }
#endif
case C4V_PropList:
#ifdef _DEBUG
assert(C4PropList::PropLists.Has(Data.PropList));
if (!Data.PropList->Status)
{ LogF("Warning: using ptr on deleted object %p (%s)!", static_cast<void*>(Data.PropList), Data.PropList->GetName()); }
#endif