INSIDE CRT: Debug HEAP Management

xiaoxiao2021-03-05  19

Transfer from www.codeguru.com

When you compile a debug build of your program with Visual Studio and run it in debugger, you can see that the memory allocated or deallocated has funny values, such as 0xCDCDCDCD or 0xDDDDDDDD. This is the result of the work Microsoft has put in to detect Memory Corruption and Leaks in The Win32 Platform. In this Article, I WILL EXPLAIN How memory allocation / deallocation is done via new / delete or malloc / free.

First, I WILL EXPLAIN What All these Values ​​That You See, Like CD, DD, And So Forth, Mean.

ValueNameDescription0xCDClean memory via MemoryAllocated malloc or new but never written by the application.0xDDDead MemoryMemory that has been released with delete or free. It is used to detect writing through dangling pointers.0xFDFence MemoryAlso known as "no mans land." This is used to wrap the allocated memory (like surrounding it with fences) and is used to detect indexing arrays out of bounds.0xAB (allocated Block?) Memory allocated by LocalAlloc (). 0xBAADF00DBad FoodMemory allocated by LocalAlloc () with LMEM_FIXED, but not yet written to. 0xcc WHEN THE CODE IS Compiled with The / Gz Option, Uninitialized Variables Are Automatical Assigned to this value (at by byte level).

If you take a look at dbgheap.c, you can see how little of these values ​​are defined:

Static unsigned char _bnomanslandfill = 0xfd; / * Fill no-man's land with this * /

Static unsigned char _bdeadlandfill = 0xdd; / * Fill Free Objects with this * /

Static unsigned char _bcleanlandfill = 0xcd; / * Fill new Objects with this * /

BEFORE GoING ANY FURTHER, TAKE A LOOK AT The Memory Management Function That I Will Refer in this article.

FunctionDescriptionmallocC / C function that allocates a block of memory from the heap The implementation of the C operator new is based on malloc._malloc_dbgDebug version of malloc;. Only available in the debug versions of the run-time libraries _malloc_dbg is a debug version of. . the malloc function When _DEBUG is not defined, each call to _malloc_dbg is reduced to a call to malloc Both malloc and _malloc_dbg allocate a block of memory in the base heap, but _malloc_dbg offers several debugging features:. buffers on either side of the user portion of the block to test for leaks, a block type parameter to track specific allocation types, and filename / linenumber information to determine the origin of allocation requests.freeC / C function that frees an allocated block. The implementation of C operator delete is based On Free._Free_dbgdebug Version of Free; Only Available In The debracies. The _free_dbg function is a debug version of the free function. When _DEBUG is not defined, each call to _free_dbg is reduced to a call to free Both free and _free_dbg free a memory block in the base heap, but _free_dbg accommodates two debugging features:. The ability to keep freed blocks in the heap '

s linked list to simulate low memory conditions and a block type parameter to free specific allocation types.LocalAllocGlobalAllocWin32 API to allocate the specified number of bytes from the heap. Windows memory management does not provide a separate local heap and global heap.LocalFreeGlobalFreeWin32 API free the specified local memory object and invalidates its handle.HeapAllocWin32 API allocates a block of memory from a heap. The allocated memory is not movable.HeapFreeWin32 API frees a memory block allocated from a heap by the HeapAlloc or HeapReAlloc function.There are many other functions that DEAL WITH MEMORY Management. for a completion view please refer to msdn.

Note: Because this article is about memory management in a debug build, all the references to malloc and free in the following are actually references to their debug versions, _malloc_dbg and _free_dbg.

Compile The Following Code And Run It in The Debugger, Walking Step by Steo IT To See How Memory Is Allocated and deallocated.

Int main (int Argc, char * argv [])

{

Char * buffer = new char [12];

DELETE [] BUFFER;

Return 0;

}

Here, 12 bytes are dynamically allocated, but the CRT allocates more than that by wrapping the allocated block with bookkeeping information For each allocated block, the CRT keeps information in a structure called _CrtMemBlockHeader, which is declared in DBGINT.H.:

#define nnomanslandsize 4

Typedef struct _crtMemBlockHeader

{

Struct_crtmemblockheader * pblockheadernexT;

Struct_crtmemblockheader * PblockHeaderPrev;

Char * szfilename;

INT NLINE;

SIZE_T NDATASIZE;

Int nblockuse;

Long Lrequest;

Unsigned char gap [nnomanslandsize]; / * followed by:

* unsigned char data [nDataSize];

* unsigned char annothergap [nnomanslandsize];

* /

} _CRTMEMBLOCKHEADER;

IT Stores The Following Information:

FieldDescriptionpBlockHeaderNextA pointer to the next block allocated, but next means the previous allocated block because the list is seen as a stack, with the latest allocated block at the top.pBlockHeaderPrevA pointer to the previous block allocated; this means the block that was allocated after the current block.szFileNameA pointer to the name of the file in which the call to malloc was made, if known.nLineThe line in the source file indicated by szFileName at which the call to malloc was made, if known.nDataSizeNumber of bytes requestednBlockUse0 - Freed block, but not released back to the Win32 heap1 - Normal block (allocated with new / malloc) 2 - CRT blocks, allocated by CRT for its own uselRequestCounter incremented with each allocationgapA zone of 4 bytes (in the current implementation) filled with 0xFD, Fencing The Data Block, of nDataSize bytes. Another block filled with 0xfd of the Same size Follows the data.

Most of the work of heap block allocation and deallocation are made by HeapAlloc () and HeapFree (). When you request 12 bytes to be allocated on the heap, malloc () will call HeapAlloc (), requesting 36 more bytes.

Blocksize = sizeof (_CRTMEMBLOCKHEADER) NSIZE NNOMANSLANDSIZE;

Malloc Requests Space for the 12 bytes We need (nsize), Plus 32 bytes for the _crtmemblockheader structure and another nnomanslandsize bytes (4 bytes) to fence the data zone and close the gap.

But, HeapAlloc () will allocate even more bytes: 8 bytes below the requested block (that is, at a lower address) and 32 above it (that is, at a bigger address) It also initializes the requested block to 0xBAADF00D (bad. Food) .Then, Malloc () Fills The _CrtMEMBLOCKHEADER BLOCK WITH INFORMATION AND INITISES The DATA Block with 0xcd and no mans land with 0xfd.

Here is a Table That Shows HOW MEMORY LOOKS AFTER The Call To Heapalloc () And After Malloc () Returns. For a completion, see: all values ​​are in hex.

Addressafter HeapAlloc () after malloc () 00320FD800320FDC00320FE000320FE400320FE800320FEC00320FF000320FF400320FF800320FFC0032100000321004003210080032100C0032101000321014003210180032101C0032102000321024003210280032102C 09 00 09 01E8 07 18 000D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD BA0D F0 AD baab ab abab AB ab ab Abstract 00 00 00 00 0079 00Ee 04 EE 0040 05 32 0040 05 32 00 09 00 09 01E8 07 18 00 00 00 00 00 00 00 00 00 00 00 000 000 0001 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 001 00 00fd fd fd fdcd CD CD CDCD CD CD CD CD CD CDFD FD FD FDAB AB AB ABAB AB AB Ab Ab AB 00 00 00 00 00 00 00 00 00 00 00100 001 00Ee 04 EE 0040 05 32 0040 05 32 00 00 00 00 00 00 00 00 00 0019 00ee 04 EE 0040 05 32 0040 05 3200

Colors:

Green: Win32 Bookkeested Info Blue: Block Size Requested by Malloc and Filled with Bad Food Magenta: _CRTMEMBLOCKHEADER BLOCK Red: No Mans Land Black: Requested Data Block

In this Example, after the call to malloc () Returns, Buffer Will Point To Memory Address 0x00321000.

When you call delete / free, the CRT will set the block it requested from HeapAlloc () to 0xDD, indicating this is a free zone. Normally after this, free () will call HeapFree () to give back the block to the Win32 heap , in which case the block will be overwritten with 0xFEEEEEEE, to indicate Win32 heap free memory.You can avoid this by using the CRTDBG_DELAY_FREE_MEM_DF flag to _CrtSetDbgFlag (). It prevents memory from actually being freed, as for simulating low-memory conditions. When this bit is on, freed blocks are kept in the debug heap's linked list but are marked as _FREE_BLOCK. This is useful if you want to detect dangling pointers errors, which can be done by verifying if the freed block is written with 0xDD pattern or something Else. Use _ crtcheckmemory () to verify the heap.s integrity.

The next Table shows how the memory looks during the free (), before heapfree () is caled and offwards.

AddressBefore HeapFree () After HeapFree () 00320FD800320FDC00320FE000320FE400320FE800320FEC00320FF000320FF400320FF800320FFC0032100000321004003210080032100C0032101000321014003210180032101C0032102000321024003210280032102C 09 00 09 015E 07 18 00DD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDDD DD DD DDAB AB AB AB AB AB 00 00 00 00 00 0079 00Ee 04 EE 0040 05 32 0040 05 32 00 09 09 015E 04 18 00 00> 2B 32 0078 01 32 00E Fe EE FeE EE Fe Ee Feee Fe EE Fe EE Fe EE FeE EE FeE EE Fe EE Fe EEE Fe EE Fe EE Fe EEE Fe Ee FeE EE FeE Ee Fee Fe EE Fe Ee Feee Fe Ee Fe

Colors:

Green: Win32 Bookkeeping Info Blue: Crt Block Filled with Dead Memory Gray: Memory Given Back to Win32 HEAP

The two tables above are put in a single, more detailed, table below: Address (hex) OffsetHeapAllocmallocFree before HeapFreeFree after HeapFreeDescription00320FD8-4001090009010900090109000901090082Win32 Heap info00320FDC-36001807E8001807E80018075E0018045EWin32 Heap info00320FE0-32BAADF00D00320798DDDDDDDD00322BE0pBlockHeaderNext00320FE4-28BAADF00D00000000DDDDDDDD00320178pBlockHeaderPrev00320FE8-24BAADF00D00000000DDDDDDDDFEEEEEEEszFileName00320FEC-20BAADF00D00000000DDDDDDDDFEEEEEEEnLine00320FF0-16BAADF00D0000000CDDDDDDDDFEEEEEEEnDataSize00320FF4-12BAADF00D00000001DDDDDDDDFEEEEEEEnBlockUse00320FF8-8BAADF00D0000002EDDDDDDDDFEEEEEEElRequest00320FFC-4BAADF00DFDFDFDFDDDDDDDDDFEEEEEEEgap ( no mans land) 003210000BAADF00DCDCDCDCDDDDDDDDDFEEEEEEEData requested00321004 4BAADF00DCDCDCDCDDDDDDDDDFEEEEEEEData requested00321008 8BAADF00DCDCDCDCDDDDDDDDDFEEEEEEEData requested0032100C 12BAADF00DFDFDFDFDDDDDDDDDFEEEEEEENo mans land00321010 16ABABABABABABABABABABABABFEEEEEEEWin32 Heap info00321014 20ABABABA BABABABABABABABABFEEEEEEEWin32 Heap info00321018 24000000000000000000000000FEEEEEEEWin32 Heap info0032101C 28000000000000000000000000FEEEEEEEWin32 Heap info00321020 32000900790009007900090079FEEEEEEEWin32 Heap info00321024 3600EE04EE00EE04EE00EE04EEFEEEEEEEWin32 Heap info00321028 40003205400032054000320540FEEEEEEEWin32 Heap info0032102C 44003205400032054000320540FEEEEEEEWin32 Heap info

About the AuthorMarius Bancila is a software developer working for a company that provides industrial automation solutions, but he is mainly focused on GUI design with MFC. When he discovered the .NET framework quickly fell inlove. He considers that CodeGuru is the best place on internet To spend time.

转载请注明原文地址:https://www.9cbs.com/read-39234.html

New Post(0)