📄 dbgheap.c
字号:
)
{
_free_dbg_nolock(pUserData, _NORMAL_BLOCK);
}
/***
*void _free_dbg() - free a block in the debug heap
*
*Purpose:
* Frees any type of supported block.
*
*Entry:
* void * pUserData - pointer to a (user portion) of memory block in the
* debug heap
* int nBlockUse - block type
*
*Return:
* <void>
*
*******************************************************************************/
extern "C" _CRTIMP void __cdecl _free_dbg(
void * pUserData,
int nBlockUse
)
{
/* lock the heap
*/
_mlock(_HEAP_LOCK);
__try {
/* allocate the block
*/
_free_dbg_nolock(pUserData, nBlockUse);
}
__finally {
/* unlock the heap
*/
_munlock(_HEAP_LOCK);
}
}
extern "C" void __cdecl _free_dbg_nolock(
void * pUserData,
int nBlockUse
)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
/* verify heap before freeing */
if (check_frequency > 0)
if (check_counter == (check_frequency - 1))
{
_ASSERTE(_CrtCheckMemory());
check_counter = 0;
}
else
check_counter++;
if (pUserData == NULL)
return;
/* check if the heap was not allocated by _aligned routines */
if ( nBlockUse == _NORMAL_BLOCK)
{
if ( CheckBytes((unsigned char*)((uintptr_t)pUserData & ~(sizeof(uintptr_t) -1)) -nAlignGapSize,_bAlignLandFill, nAlignGapSize))
{
// We don't know (yet) where (file, linenum) pUserData was allocated
_RPT1(_CRT_ERROR, "The Block at 0x%p was allocated by aligned routines, use _aligned_free()", pUserData);
errno = EINVAL;
return;
}
}
/* forced failure */
if ((_pfnAllocHook) && !(*_pfnAllocHook)(_HOOK_FREE, pUserData, 0, nBlockUse, 0L, NULL, 0))
{
_RPT0(_CRT_WARN, "Client hook free failure.\n");
return;
}
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
/* if we didn't already check entire heap, at least check this object */
if (!(_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF))
{
/* check no-mans-land gaps */
if (!CheckBytes(pHead->gap, _bNoMansLandFill, nNoMansLandSize))
{
if (pHead->szFileName)
{
_RPT5(_CRT_ERROR, "HEAP CORRUPTION DETECTED: before %hs block (#%d) at 0x%p.\n"
"CRT detected that the application wrote to memory before start of heap buffer.\n"
_ALLOCATION_FILE_LINENUM,
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead),
pHead->szFileName,
pHead->nLine);
}
else
{
_RPT3(_CRT_ERROR, "HEAP CORRUPTION DETECTED: before %hs block (#%d) at 0x%p.\n"
"CRT detected that the application wrote to memory before start of heap buffer.\n",
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead));
}
}
if (!CheckBytes(pbData(pHead) + pHead->nDataSize, _bNoMansLandFill, nNoMansLandSize))
{
if (pHead->szFileName)
{
_RPT5(_CRT_ERROR, "HEAP CORRUPTION DETECTED: after %hs block (#%d) at 0x%p.\n"
"CRT detected that the application wrote to memory after end of heap buffer.\n"
_ALLOCATION_FILE_LINENUM,
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead),
pHead->szFileName,
pHead->nLine);
}
else
{
_RPT3(_CRT_ERROR, "HEAP CORRUPTION DETECTED: after %hs block (#%d) at 0x%p.\n"
"CRT detected that the application wrote to memory after end of heap buffer.\n",
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead));
}
}
}
RTCCALLBACK(_RTC_FuncCheckSet_hook,(0));
if (pHead->nBlockUse == _IGNORE_BLOCK)
{
_ASSERTE(pHead->nLine == IGNORE_LINE && pHead->lRequest == IGNORE_REQ);
/* fill the entire block including header with dead-land-fill */
memset(pHead, _bDeadLandFill,
sizeof(_CrtMemBlockHeader) + pHead->nDataSize + nNoMansLandSize);
_free_base(pHead);
RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
return;
}
/* CRT blocks can be freed as NORMAL blocks */
if (pHead->nBlockUse == _CRT_BLOCK && nBlockUse == _NORMAL_BLOCK)
nBlockUse = _CRT_BLOCK;
/* Error if freeing incorrect memory type */
_ASSERTE(pHead->nBlockUse == nBlockUse);
/* keep track of total amount of memory allocated */
_lCurAlloc -= pHead->nDataSize;
/* optionally reclaim memory */
if (!(_crtDbgFlag & _CRTDBG_DELAY_FREE_MEM_DF))
{
/* remove from the linked list */
if (pHead->pBlockHeaderNext)
{
pHead->pBlockHeaderNext->pBlockHeaderPrev = pHead->pBlockHeaderPrev;
}
else
{
_ASSERTE(_pLastBlock == pHead);
_pLastBlock = pHead->pBlockHeaderPrev;
}
if (pHead->pBlockHeaderPrev)
{
pHead->pBlockHeaderPrev->pBlockHeaderNext = pHead->pBlockHeaderNext;
}
else
{
_ASSERTE(_pFirstBlock == pHead);
_pFirstBlock = pHead->pBlockHeaderNext;
}
/* fill the entire block including header with dead-land-fill */
memset(pHead, _bDeadLandFill,
sizeof(_CrtMemBlockHeader) + pHead->nDataSize + nNoMansLandSize);
_free_base(pHead);
}
else
{
pHead->nBlockUse = _FREE_BLOCK;
/* keep memory around as dead space */
memset(pbData(pHead), _bDeadLandFill, pHead->nDataSize);
}
RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
}
/***
*size_t _msize() - calculate the size of specified block in the heap
*
*Purpose:
* Calculates the size of memory block (in the heap) pointed to by
* pUserData.
*
* For 'normal' memory block.
*
*Entry:
* void * pUserData - pointer to a memory block in the heap
*
*Return:
* size of the block
*
*******************************************************************************/
extern "C" _CRTIMP size_t __cdecl _msize (
void * pUserData
)
{
return _msize_dbg(pUserData, _NORMAL_BLOCK);
}
/***
*size_t _msize_dbg() - calculate the size of specified block in the heap
*
*Purpose:
* Calculates the size of memory block (in the heap) pointed to by
* pUserData.
*
*Entry:
* void * pUserData - pointer to a (user portion) of memory block in the
* debug heap
* int nBlockUse - block type
*
* For any type of supported block.
*
*Return:
* size of the block
*
*******************************************************************************/
extern "C" _CRTIMP size_t __cdecl _msize_dbg (
void * pUserData,
int nBlockUse
)
{
size_t nSize;
_CrtMemBlockHeader * pHead;
/* validation section */
_VALIDATE_RETURN(pUserData != NULL, EINVAL, -1);
/* verify heap before getting size */
if (check_frequency > 0)
if (check_counter == (check_frequency - 1))
{
_ASSERTE(_CrtCheckMemory());
check_counter = 0;
}
else
check_counter++;
_mlock(_HEAP_LOCK); /* block other threads */
__try {
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
/* CRT blocks can be treated as NORMAL blocks */
if (pHead->nBlockUse == _CRT_BLOCK && nBlockUse == _NORMAL_BLOCK)
nBlockUse = _CRT_BLOCK;
/* The following assertion was prone to false positives - JWM */
/* if (pHead->nBlockUse != _IGNORE_BLOCK) */
/* _ASSERTE(pHead->nBlockUse == nBlockUse); */
nSize = pHead->nDataSize;
}
__finally {
_munlock(_HEAP_LOCK); /* release other threads */
}
return nSize;
}
/***
*long _CrtSetBreakAlloc() - set allocation on which to break
*
*Purpose:
* set allocation on which to break
*
*Entry:
* long lBreakAlloc
*
*Exit:
* return previous break number
*
*Exceptions:
*
*******************************************************************************/
extern "C" _CRTIMP long __cdecl _CrtSetBreakAlloc(
long lNewBreakAlloc
)
{
long lOldBreakAlloc = _crtBreakAlloc;
_crtBreakAlloc = lNewBreakAlloc;
return lOldBreakAlloc;
}
/***
*void _CrtSetDbgBlockType() - change memory block type
*
*Purpose:
* change memory block type
*
*Entry:
* void * pUserData - pointer to a (user portion) of memory block in the
* debug heap
* int nBlockUse - block type
*
*Exit:
*
*Exceptions:
*
*******************************************************************************/
extern "C" _CRTIMP void __cdecl _CrtSetDbgBlockType(
void * pUserData,
int nBlockUse
)
{
_CrtMemBlockHeader * pHead;
_mlock(_HEAP_LOCK); /* block other threads */
__try {
/* If from local heap, then change block type. */
if (_CrtIsValidHeapPointer(pUserData))
{
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
pHead->nBlockUse = nBlockUse;
}
}
__finally {
_munlock(_HEAP_LOCK); /* release other threads */
}
return;
}
/*---------------------------------------------------------------------------
*
* Client-defined allocation hook
*
--------------------------------------------------------------------------*/
/***
*_CRT_ALLOC_HOOK _CrtSetAllocHook() - set client allocation hook
*
*Purpose:
* set client allocation hook
*
*Entry:
* _CRT_ALLOC_HOOK pfnNewHook - new allocation hook
*
*Exit:
* return previous hook
*
*Exceptions:
* None
*
*******************************************************************************/
extern "C" _CRTIMP _CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook(
_CRT_ALLOC_HOOK pfnNewHook
)
{
_CRT_ALLOC_HOOK pfnOldHook = _pfnAllocHook;
_pfnAllocHook = pfnNewHook;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -