99 lines
2.8 KiB
C++
99 lines
2.8 KiB
C++
// BstrDebug.cpp: implementation of the CBstrDebug class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#ifdef MEM_DBG
|
|
CBstrDebug g_allocs;
|
|
ULONG g_breakOnBstrAlloc = -1;
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CBstrDebug::CBstrDebug() :
|
|
m_allocs("BstrDebugging",LK_DFLT_MAXLOAD,LK_LARGE_TABLESIZE,0), m_numAllocs(0)
|
|
{
|
|
|
|
}
|
|
|
|
CBstrDebug::~CBstrDebug()
|
|
{
|
|
if (m_allocs.Size() > 0)
|
|
{
|
|
ATLTRACE("BstrDebug found leaks!!!\n");
|
|
LK_RETCODE lkrc;
|
|
BSTRLEAKMAP::CConstIterator it;
|
|
const BSTRLEAKMAP& htConst = m_allocs;
|
|
for (lkrc = htConst.InitializeIterator(&it) ;
|
|
lkrc == LK_SUCCESS ;
|
|
lkrc = htConst.IncrementIterator(&it))
|
|
{
|
|
ATLTRACE("Leak allocated from %s Line %d (#%u)\n", it.Record()->m_v->file,
|
|
it.Record()->m_v->line, it.Record()->m_v->num);
|
|
delete it.Record()->m_v; // Hah hah. Try and catch me compiler.
|
|
}
|
|
htConst.CloseIterator(&it);
|
|
}
|
|
}
|
|
|
|
BSTR CBstrDebug::track(BSTR mem, LPSTR message, int line)
|
|
{
|
|
if (!mem)
|
|
return NULL; // We don't care about null pointers...
|
|
|
|
ULONG numA = InterlockedIncrement((long*)&m_numAllocs);
|
|
|
|
#ifdef MEM_DBG
|
|
if (numA == g_breakOnBstrAlloc)
|
|
DebugBreak();
|
|
#endif
|
|
|
|
const BSTRLEAKMAP::ValueType *pOut = NULL;
|
|
LK_RETCODE lkrc = m_allocs.FindKey((LONG_PTR) mem, &pOut);
|
|
if (lkrc == LK_SUCCESS && pOut != NULL)
|
|
{
|
|
ATLTRACE("BstrDebug::track: Already tracking memory allocated from %s line %d (#%u). Called from %s line %d (#%u). Keeping original\n",
|
|
pOut->m_v->file, pOut->m_v->line, pOut->m_v->num, message, line, numA);
|
|
m_allocs.AddRefRecord(pOut, -1);
|
|
}
|
|
else
|
|
{
|
|
BSTRLEAKMAP::ValueType *pair =
|
|
new BSTRLEAKMAP::ValueType((LONG_PTR) mem,new bstrAllocInfo(message,line,numA), "BSTRDbg");
|
|
if (pair)
|
|
{
|
|
if (m_allocs.InsertRecord(pair) != LK_SUCCESS)
|
|
{
|
|
ATLTRACE("BstrDebug::track: Couldn't insert record for allocation at %s line %d (#%u).\n",
|
|
message, line, numA);
|
|
delete pair;
|
|
}
|
|
}
|
|
}
|
|
return mem;
|
|
}
|
|
|
|
void CBstrDebug::release(BSTR mem, LPSTR message, int line)
|
|
{
|
|
if (!mem)
|
|
return;
|
|
|
|
const BSTRLEAKMAP::ValueType *pOut = NULL;
|
|
LK_RETCODE lkrc = m_allocs.FindKey((LONG_PTR) mem, &pOut);
|
|
if (lkrc == LK_SUCCESS && pOut != NULL)
|
|
{
|
|
delete pOut->m_v;
|
|
m_allocs.AddRefRecord(pOut, -1);
|
|
m_allocs.DeleteKey((LONG_PTR) mem);
|
|
}
|
|
else
|
|
{
|
|
ATLTRACE("BstrDebug::release: Already released memory. Called from %s line %d.\n",
|
|
message, line);
|
|
}
|
|
}
|
|
|