2025-04-27 07:49:33 -04:00

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);
}
}