/*************************************** **************************************
* Dbgheap. C-Debug CRT heap Functions
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* Purpose:
* Defines DEBUG Versions of heap functions.
*
**************************************** ***************************************/
/*---------------------------------------------------------------------------
*
* Memory Management
*
--------------------------------------------------------------------------*/
/*************************************** *************************************
* Static int checkbytes ()-verify byte range set to proper value
*
* Purpose:
* Verify byte range set to proper value
*
* Entry:
* Unsigned char * pb-pointer to start of byte range
* Unsigned char bcheck-value byte range shoshould be set
* Size_t nsize-size of byte range to be checked
*
* Return:
* True-if all bytes in range equal bcheck
* False otherwise
*
**************************************** ***************************************/
Extern "C" static int _ cdecl checkbytes (
Unsigned char * pb,
Unsigned char bcheck,
Size_t nsize
)
{
Int bokay = true;
While (nsize --)
{
If (* pb ++! = Bcheck)
{
/* Internal error report is just noise; Calling functions all report results-jwm */
/* _ Rpt3 (_ crt_warn, "memory check error at 0x % P = 0x % 02x, shocould be 0x % 02x./N ",*/
/* (Byte *) (pb-1), * (pb-1), bcheck );*/
Bokay = false;
}
}
Return bokay;
}
/***
* Int _ crtcheckmemory ()-check heap integrity
*
* Purpose:
* Confirm integrity of DEBUG heap. Call _ heapchk to validate underlying
* Heap.
*
* Entry:
* Void
*
* Return:
* True-If debug and underlying heap appear valid
* False otherwise
*
**************************************** ***************************************/
Extern "C" _ cribd int _ cdecl _ crtcheckmemory (
Void
)
{
Int allokay;
Int nheapcheck;
_ Crtmemblockheader * phead;
If (! (_ Crtdbgflag & _ crtdbg_alloc_mem_df ))
Return true;/* Can't do any checking */
_ Mlock (_ heap_lock);/* block other threads */
_ Try {
/* Check underlying heap */
Nheapcheck = _ heapchk ();
If (nheapcheck! = _ Heapempty & nheapcheck! = _ Heapok)
{
Switch (nheapcheck)
{
Case _ heapbadbegin:
_ Rpt0 (_ crt_warn, "_ heapchk fails with _ heapbadbegin./N ");
Break;
Case _ heapbadnode:
_ Rpt0 (_ crt_warn, "_ heapchk fails with _ heapbadnode./N ");
Break;
Case _ heapend:
_ Rpt0 (_ crt_warn, "_ heapchk fails with _ heapbadend./N ");
Break;
Case _ heapbadptr:
_ Rpt0 (_ crt_warn, "_ heapchk fails with _ heapbadptr./N ");
Break;
Default:
_ Rpt0 (_ crt_warn, "_ heapchk fails with unknown return value! /N ");
Break;
}
Allokay = false;
}
Else
{
Allokay = true;
/* Check all allocated blocks */
For (phead = _ pfirstblock; phead! = NULL; phead = phead-> pblockheadernext)
{
Int okay = true;/* this block okay? */
Unsigned char * blockuse;
If (_ block_type_is_valid (phead-> nblockuse ))
Blockuse = (unsigned char *) szblockusename [_ block_type (phead-> nblockuse)];
Else
Blockuse = (unsigned char *) "damaged ";
/* Check no-mans-land gaps */
If (! Checkbytes (phead-> GaP, _ bnomanslandfill, nnomanslandsize ))
{
_ Rpt3 (_ crt_warn, "heap resume uption detected: Before % hs block (# % d) at 0x % P./N"
"CRT detected that the application wrote to memory before start of heap buffer./N ",
Blockuse, phead-> lrequest, (byte *) pbdata (phead ));
Okay = false;
}
If (! Checkbytes (pbdata (phead) + phead-> ndatasize, _ bnomanslandfill,
Nnomanslandsize ))
{
_ Rpt3 (_ crt_warn, "heap resume uption detected: After % hs block (# % d) at 0x % P./N"
"CRT detected that the application wrote to memory after end of heap buffer./N ",
Blockuse, phead-> lrequest, (byte *) pbdata (phead ));
Okay = false;
}
/* Free blocks shocould remain undisturbed */
If (phead-> nblockuse ==_ free_block &&
! Checkbytes (pbdata (phead), _ bdeadlandfill, phead-> ndatasize ))
{
_ Rpt1 (_ crt_warn, "heap resume uption detected: On top of free block at 0x % P./N"
"CRT detected that the application wrote to a heap buffer that was freed./N ",
(Byte *) pbdata (phead ));
Okay = false;
}
If (! Okay)
{
/* Report some more statistics about the broken object */
If (phead-> szfilename! = NULL)
_ Rpt3 (_ crt_warn, "% hs allocated at file % hs (% d)./N ",
Blockuse, phead-> szfilename, phead-> nline );
_ Rpt3 (_ crt_warn, "% hs located at 0x % P is % IU bytes long./N ",
Blockuse, (byte *) pbdata (phead), phead-> ndatasize );
Allokay = false;
}
}
}
}
_ Finally {
_ Munlock (_ heap_lock);/* release other threads */
}
Return allokay;
}