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