Esempio n. 1
0
int CMemLeakDetector::CrtAllocHook(int allocType, void *userData, size_t size, int blockType, long requestNumber, const unsigned char *filename, int lineNumber)
{
#ifdef _DEBUG

	UNREFERENCED_PARAMETER(size);
	UNREFERENCED_PARAMETER(filename);
	UNREFERENCED_PARAMETER(lineNumber);

	bool trackAllocation = true;

	// do not memory tracking on crt blocks or if detection is disabled for this thread
	if(blockType == _CRT_BLOCK)
		trackAllocation = false;

	// get the current debug flag bits, only track debug allocations
	// INFO: The _CrtSetDbgFlag does NOT store its flags thread local!
	//       Therefore if one thread deactivates memory tracking, an allocation in another thread could not be tracked.
	//       This MFC default usage behavior and must be implemented, otherwise many MFC memory leak will be reported.
	//       The function does not affect applications without MFC, because this flag is not used by applications without MFC.
	int debugFlags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	if(!(debugFlags & _CRTDBG_ALLOC_MEM_DF))
		trackAllocation = false;

	// prevent the current thread from re-entering on allocs/reallocs/frees
	// that we or the CRT do internally to record the data we collect.
	if(trackAllocation)
	{
		// handle the allocation request
		switch(allocType)
		{
			case _HOOK_ALLOC:
				g_MemLeakDetector.TrackAllocInfo(requestNumber, 0);
				break;

			case _HOOK_FREE:
				g_MemLeakDetector.RemoveAllocInfo(pHdr(userData)->lRequest);
				break;

			case _HOOK_REALLOC:
				g_MemLeakDetector.RemoveAllocInfo(pHdr(userData)->lRequest);
				g_MemLeakDetector.TrackAllocInfo(requestNumber, 0);
				break;
		}
	}

	if(g_MemLeakDetector.m_OldHook)
		return g_MemLeakDetector.m_OldHook(blockType, userData, size, blockType, requestNumber, filename, lineNumber);
	
#endif // _DEBUG

	return TRUE;
}
Esempio n. 2
0
void operator delete(
        void *pUserData
        )
{
        _CrtMemBlockHeader * pHead;

        RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

        if (pUserData == NULL)
            return;

        _mlock(_HEAP_LOCK);  /* block other threads */
        __TRY

            /* get a pointer to memory block header */
            pHead = pHdr(pUserData);

             /* verify block type */
            _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

            _free_dbg( pUserData, pHead->nBlockUse );

        __FINALLY
            _munlock(_HEAP_LOCK);  /* release other threads */
        __END_TRY_FINALLY

        return;
}
Esempio n. 3
0
void _vm_free( void *ptr )
#endif
{
	if (!ptr)
	{
#ifndef NDEBUG
			mprintf(("Why are you trying to free a NULL pointer?  [%s(%d)]\n", clean_filename(filename), line));
#else
			mprintf(("Why are you trying to free a NULL pointer?\n"));
		#endif
		return;
	}



#ifndef NDEBUG
	_CrtMemBlockHeader* phd = pHdr(ptr);
	int nSize = phd->nDataSize;

	TotalRam -= nSize;
	if (Cmdline_show_mem_usage)
		unregister_malloc(filename, nSize, ptr);
#endif

	_free_dbg(ptr, _NORMAL_BLOCK);
}
Esempio n. 4
0
_CrtMemBlockHeader* get_head()
{
	// New blocks are added to the head of the list
	void* p = malloc(1);
	_CrtMemBlockHeader* hdr = pHdr(p);
	free(p);
	return hdr;
}
Esempio n. 5
0
void *_vm_realloc( void *ptr, int size, int quiet )
#endif
{
	// if this is the first time it's used then we need to malloc it first
	if (ptr == NULL)
		return vm_malloc(size);

	void* ret_ptr = NULL;

#ifndef NDEBUG
	// Unregistered the previous allocation
	_CrtMemBlockHeader* phd = pHdr(ptr);
	int nSize = phd->nDataSize;

	TotalRam -= nSize;
	if (Cmdline_show_mem_usage)
		unregister_malloc(filename, nSize, ptr);
#endif

	ret_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, __FILE__, __LINE__);

	if (ret_ptr == NULL)
	{
		mprintf(("realloc failed!!!!!!!!!!!!!!!!!!!\n"));

		if (quiet && (size > 0) && (ptr != NULL))
		{
			// realloc doesn't touch the original ptr in the case of failure so we could still use it
			return NULL;
		}

		Error(LOCATION, "Out of memory.  Try closing down other applications, increasing your\n"
			"virtual memory size, or installing more physical RAM.\n");
	}
#ifndef	NDEBUG
	TotalRam += size;

	// register this allocation
	if (Cmdline_show_mem_usage)
		register_malloc(size, filename, line, ret_ptr);
#endif
	return ret_ptr;
}
void _vm_free( void *ptr )
#endif
{
	if ( !ptr ) {
		return;
	}



#ifndef NDEBUG
	_CrtMemBlockHeader *phd = pHdr(ptr);
	int nSize = phd->nDataSize;

	TotalRam -= nSize;
	if(Cmdline_show_mem_usage)
		unregister_malloc(filename, nSize, ptr);
#endif

	_free_dbg(ptr,_NORMAL_BLOCK);
}
Esempio n. 7
0
static int  CrtAllocHook(int      nAllocType,
						 void   * pvData,
						 size_t   nSize,
						 int      nBlockUse,
						 long     lRequest,
						 const unsigned char * szFileName,
						 int      nLine)
{
	if (nBlockUse == _CRT_BLOCK)
	{
		return TRUE;
	}

	if (!g_inAllocHook)
	{
		g_inAllocHook = true;

		if (nAllocType == _HOOK_ALLOC)
		{
			StoreAlloc(pvData, nSize, lRequest, (g_newFile[0]) ? g_newFile : (const char*)szFileName, "", (g_newFile[0]) ? g_newLine : nLine);
		}
		else if (nAllocType == _HOOK_FREE)
		{
			if (_CrtIsValidHeapPointer(pvData))
			{
				_CrtMemBlockHeader* pHead = pHdr(pvData);
				lRequest = pHead->lRequest;
			}

			RemoveAlloc(pvData, nSize, lRequest);
		}

		// clear the new caller
		g_newFile = "";

		g_inAllocHook = false;
	}

	return TRUE;
}
/***
*void operator delete() - delete a block in the debug heap
*
*Purpose:
*       Deletes any type of block.
*
*Entry:
*       void *pUserData - pointer to a (user portion) of memory block in the
*                         debug heap
*
*Return:
*       <void>
*
*******************************************************************************/
void operator delete(
        void *pUserData
        )
{
        _CrtMemBlockHeader * pHead;

        if (pUserData == NULL)
            return;

        _mlock(_HEAP_LOCK);  /* block other threads */

        /* get a pointer to memory block header */
        pHead = pHdr(pUserData);

         /* verify block type */
        _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

        _free_dbg( pUserData, pHead->nBlockUse );

        _munlock(_HEAP_LOCK);  /* release other threads */

        return;
}
int __cdecl MyAllocHook(
   int      nAllocType,
   void   * pvData,
   size_t   nSize,
   int      nBlockUse,
   long     lRequest,
   const char * szFileName,
   int      nLine
   )
{
   // char *operation[] = { "", "allocating", "re-allocating", "freeing" };
   // char *blockType[] = { "Free", "Normal", "CRT", "Ignore", "Client" };

   if ( nBlockUse == _CRT_BLOCK )   // Ignore internal C runtime library allocations
      return( TRUE );

   _ASSERT( ( nAllocType > 0 ) && ( nAllocType < 4 ) );
   _ASSERT( ( nBlockUse >= 0 ) && ( nBlockUse < 5 ) );

	if ( nAllocType == 3 )	{
		_CrtMemBlockHeader *phd = pHdr(pvData);
		nSize = phd->nDataSize;
	} 

//	mprintf(( "Total RAM = %d\n", TotalRam ));

   mprintf(( "Memory operation in %s, line %d: %s a %d-byte '%s' block (# %ld)\n",
            szFileName, nLine, operation[nAllocType], nSize, 
            blockType[nBlockUse], lRequest ));
   if ( pvData != NULL )
      mprintf(( " at %X", pvData ));

	mprintf(("\n" ));


   return( TRUE );         // Allow the memory operation to proceed
}
Esempio n. 10
0
unsigned int allocation_id      (void* ptr) { return static_cast<unsigned int>(pHdr(ptr)->lRequest); }
Esempio n. 11
0
size_t       size               (void* ptr) { return ptr ? pHdr(ptr)->nDataSize : 0; }
Esempio n. 12
0
bool         is_free            (void* ptr) { return pHdr(ptr)->nBlockUse == _FREE_BLOCK; }
Esempio n. 13
0
bool         is_normal          (void* ptr) { return pHdr(ptr)->nBlockUse == _NORMAL_BLOCK; }
Esempio n. 14
0
bool         is_crt             (void* ptr) { return pHdr(ptr)->nBlockUse == _CRT_BLOCK; }
Esempio n. 15
0
void CMemLeakDetector::ReportLeaks()
{
#ifdef _DEBUG

	// hooks must be disabled for reporting
	assert(!m_HooksEnabled);

	if(m_AllocInfoMap.size() > 0)
	{
		// start reporting
		m_Reporter->WriteHeader(static_cast<uintx>(m_AllocInfoMap.size()));

		// we'r accessing heap-internal structures so synchronize via heap lock
		LOCK_HEAP

			// We employ a simple trick here to get a pointer to the first allocated
			// block: just allocate a new block and get the new block's memory header.
			// This works because the most recently allocated block is always placed at
			// the head of the allocated list. We can then walk the list from head to
			// tail. For each block still in out allocation list search for the entry
			// in the crt list.
#if defined(PLATFORM_WINDOWS)
		char *pHeap = new char;
		_CrtMemBlockHeader *pHeader = pHdr(pHeap)->pBlockHeaderNext;
		delete(pHeap);
#endif

		// search through all alloc entries
		for(AllocInfoMap::iterator iter = m_AllocInfoMap.begin(); iter != m_AllocInfoMap.end(); ++iter)
		{
			AllocInfo& info = (*iter).second;
			uintx request = (*iter).first;

#if defined(PLATFORM_WINDOWS)
			// search for entry in the crt list
			_CrtMemBlockHeader *pNext = pHeader;
			while(pNext && pNext->lRequest != request) pNext = pNext->pBlockHeaderNext;

			// write memory leak infos
			if(pNext && pNext->lRequest == request)
				m_Reporter->WriteLeak(request, pbData(pNext), static_cast<uintx>(pNext->nDataSize), info.m_CallstackSize, info.m_Callstack, info.m_ModuleReference, &m_ModuleInfoVector[0]);
			else
				m_Reporter->WriteLeak(request, NULL, 0, info.m_CallstackSize, info.m_Callstack, info.m_ModuleReference, &m_ModuleInfoVector[0]);
#else
			// restore old malloc functions
			//RestoreHooks();

			m_Reporter->WriteLeak(request, reinterpret_cast<void*>(request), info.m_Size, info.m_CallstackSize, info.m_Callstack, info.m_ModuleReference, NULL);

			// set hooking functions
			//SaveHooks();
			//InstallHooks();
#endif
		}

		UNLOCK_HEAP

		// finished reporting
		m_Reporter->WriteFooter();
	}

#endif // _DEBUG
}
Esempio n. 16
0
int catchMemoryAllocHook(int    allocType, 
                         void   *userData, 
                         size_t size, 
                         int    blockType, 
                         long   requestNumber, 
          const unsigned char   *filename, // Can't be UNICODE
                         int    lineNumber)
{
    _CrtMemBlockHeader *pCrtHead;
    long prevRequestNumber;
#ifdef UNICODE
    wchar_t Wname[1024] ;
    Wname[0] = '\0' ;
#endif
    // internal C library internal allocations
    if ( blockType == _CRT_BLOCK )
    {
        return( TRUE );
    }

    // check if someone has turned off mem tracing
    
    // CRT memory tracking can be turned off by the app. MFC sometimes does this temporarily.
    
    if  ((( _CRTDBG_ALLOC_MEM_DF & _crtDbgFlag) == 0) 
        &&      (   ( allocType         == _HOOK_ALLOC)     
                ||  ( allocType         == _HOOK_REALLOC)))
    {
        if (pfnOldCrtAllocHook)
        {
            pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);
        }
        return TRUE;
    }

    // protect if mem trace is not initialized
    if (g_pMemTrace == NULL)
    {
        if (pfnOldCrtAllocHook)
        {
            pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);
        }
        return TRUE;
    }

    // protect internal mem trace allocs
    if (g_pMemTrace->isLocked)
    {
        if (pfnOldCrtAllocHook)
        {
            pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);
        }
        return( TRUE);
    }
    // lock the function
    g_pMemTrace->isLocked = true;
    //
#ifdef UNICODE
    int len ;
    if (NULL != filename)
    {
        len = strlen((char *)filename) + 1 ;
        MultiByteToWideChar(CP_ACP, 0, (char *)filename, len, Wname, len) ;
    }
    else
        len = 0 ;
#else
    #define Wname (char*)filename
#endif
    if (allocType == _HOOK_ALLOC)
    {

        g_pMemTrace->addMemoryTrace((void *) requestNumber, size, Wname, lineNumber);
    }
    else
    if (allocType == _HOOK_REALLOC)
    {
        if (_CrtIsValidHeapPointer(userData))
        {
            pCrtHead = pHdr(userData);
            prevRequestNumber = pCrtHead->lRequest;
            //
            //if (pCrtHead->nBlockUse == _IGNORE_BLOCK)
            //{
            //  if (pfnOldCrtAllocHook)
            //  {
            //      pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);
            //  }
            //  goto END;
            //}
            g_pMemTrace->redoMemoryTrace((void *) requestNumber, (void *) prevRequestNumber, size, Wname, lineNumber);
        }
    }
    else
    if (allocType == _HOOK_FREE)
    {
        if (_CrtIsValidHeapPointer(userData))
        {
            pCrtHead = pHdr(userData);
            requestNumber = pCrtHead->lRequest;
            //
            //if (pCrtHead->nBlockUse == _IGNORE_BLOCK)
            //{
            //  if (pfnOldCrtAllocHook)
            //  {
            //      pfnOldCrtAllocHook(allocType, userData, size, blockType, requestNumber, filename, lineNumber);
            //  }
            //  goto END;
            //}
            g_pMemTrace->removeMemoryTrace((void *) requestNumber, userData);
        }
    }
//END:
    // unlock the function
    g_pMemTrace->isLocked = false;
    return TRUE;
}
Esempio n. 17
0
void*        next_pointer       (void* ptr) { return get_pointer(pHdr(ptr)->pBlockHeaderNext); }
Esempio n. 18
0
unsigned int allocation_line    (void* ptr) { return static_cast<unsigned int>(pHdr(ptr)->nLine); }
Esempio n. 19
0
const char*  allocation_filename(void* ptr) { return pHdr(ptr)->szFileName; }
Esempio n. 20
0
bool         is_client          (void* ptr) { return pHdr(ptr)->nBlockUse == _CLIENT_BLOCK; }
Esempio n. 21
0
bool         is_ignore          (void* ptr) { return pHdr(ptr)->nBlockUse == _IGNORE_BLOCK; }