[old article moved] In-depth analysis of the Win32 CRT debug heap

Source: Internet
Author: User

09 Years of translating things.

See the original: http://www.nobugs.org/developer/win32/debug_crt_heap.html

In Devicestudio debug compilation mode, the heap memory allocation operations in the CRT----including malloc () and free ()----Use a special, easy-to-debug version, which we call the CRT debug Heap (hereinafter referred to as CDH). Compared to the electro-optical Flint (blazingly, I can not think of a more precise statement) of the operational efficiency, debug version more attention to the location of the heap error, it through the following three ways to achieve the appeal:

1. Surround the newly allocated memory with a guarded memory block so that the buffer overload and the under load can be detected. The so-called guarded memory block is a series of memory bytes filled with 0XFD, also known as the "Land of the Lord."

2. Initialize the newly requested memory with a special value (0XCD).

3. Fill (0XDD) The freed memory with a special value at the same time.

To make it easier to remember, you can understand the above values for padding:

1.0xcd means clean Memory.

2.0xdd means dead Memory.

3.0xfd means fences (the fence).

CDH Most of the work is done by the heap functions HeapAlloc () and HeapFree () in the Win32 API, and the chunking and management of the virtual address space for each process 4Gb is done by the Kernel32.dl heap in Win32 itself.

When you call malloc (8) to allocate 8 bytes of memory, CDH calls HeapAlloc () to request 48 bytes of memory, and the additional 40 bytes are used to hold additional information about the memory block----such as source files and line numbers that call malloc (), and points up/ A pointer to the next memory block. In the list that follows, all the CRT debugging information is marked in red.

Heaoalloc () itself also requires a record book (bookkeeping) information, in fact, a heaoalloc () call will retain 80 bytes of memory in the process address space, where 8 bytes of bookkeeping information appears before the actual 40 bytes used, The remaining 32 bytes are after the 40 bytes actually used. In the following list, the Win32 heap bookkeeping information is marked as gray. Finally, the memory returned by HeapAlloc () is always initialized to 0xbaadf00d by 14-byte alignment. By the way: When you request a memory page using a virtual memory manager that manages memory through VirtualAlloc (), the retrieved memory page is initialized to 0, so you can conclude that HeapAlloc () performs additional initialization work in the above pattern.

When the CRT obtains 40 bytes of memory, it fills in its own bookkeeping information. The first two words, word, are used to store pointers to blocks of memory in the "previous" and "later" CRT stacks. This is not literally understood here, since the so-called Pointer to the "latter" block of memory actually points to the memory block allocated before the memory block in chronological order, and the pointer to "previous" points to the next block of memory to be allocated. This is named because the memory block list starts with the last allocated block of memory. Also, in order for the heap inspection code to traverse each block of memory, CDH also holds the address of the first and last memory (_pfirstblock and _plastblock).


If the file name and line number where the malloc () code is called are known, they will be saved in the fourth word, followed by a word that indicates how much bytes of memory the block has requested. The following word is the Type field, equal to 1 for the normal block assigned by new or malloc (), and 2 for the block that the CRT allocates for internal use. 0 represents blocks that have been released by the user but have not yet been returned to the Win32 heap (see below). Typically, the new application memory block is equal to 1. The last piece is the counter, each time the memory allocation counter plus 1 is executed.


The 8 bytes of memory that are obtained by malloc () are surrounded by useless memory. These empty memory is populated with 0XFD, and when the entire memory block is free (), the CRT checks to see if the value of these empty memory stores is still 0xfd. If the value changes, the program has an error. Unfortunately, errors can happen much earlier than the check-up, and if more accurate checks are needed, you can use purify or boundschecker, they can get the program to stop at the point where the memory crashes, and if you don't want to spend money, you can wait until I write an article to show you how to implement this feature smartly.

The 8 bytes of memory that are actually being used are initialized to 0xCD, and if there is a continuous 0xcd in the middle of your object, then you must have forgotten to initialize something.

When you call Free () to release the above 8 bytes of memory, the CRT will first populate all 48 bytes of memory (including bookkeeping information) with 0XDDDDDDDD, so that you can check the value of this memory to see if there is a right written in the block after it has been released (such as using a wild pointer to write memory).

Next, the CRT typically calls the HeapFree () function to return this memory block to the Win32 heap, which populates the Win32 heap with 0xFEEEFEEE. Note that the CRT does not maintain a "free Block List", which is done by HeapFree (), which means that the free list is maintained by the Win32 heap.

However, you can let the CRT not return the freed memory block to the Win32 heap (that is, do not call HeapFree ()), by passing _CRTDBG_DELAY_FREE_MEM_DF to _CrtSetDbgFlag (), This will come in handy when you follow a wild pointer error, in which case the memory will not be reused, so the value of the freed memory must be 0xDDDDDDDD, not the memory you have written. You can call _CrtCheckMemory () to check if the freed memory has been tampered with. This function requires an explicit call by default, and you can pass _CRTDBG_CHECK_ALWAYS_DF to _CrtSetDbgFlag () so that _crtcheckmemory () is called each time the memory is allocated and freed

An example:

The following is a table of memory changes that call P = malloc (8) and then call Free (p), and malloc (8) Returns a pointer to 0x00321000, which I listed as the offset memory value so that you can find your own allocated memory information.

Address

Offset

After HeapAlloc ()

After malloc ()

During free ()

After HeapFree ()

Comments

0x00320fd8

-40

0x01090009

0x01090009

0x01090009

0x0109005a

Win32 Heap Info

0x00320fdc

-36

0x01090009

0x00180700

0x01090009

0x00180400

Win32 Heap Info

0x00320fe0

-32

0xbaadf00d

0x00320798

0xDDDDDDDD

0x00320448

Ptr to next CRT heap block (allocated earlier in time)

0x00320fe4

-28

0xbaadf00d

0x00000000

0xDDDDDDDD

0x00320448

Ptr to prev CRT heap block (allocated later in time)

0x00320fe8

-24

0xbaadf00d

0x00000000

0xDDDDDDDD

0xFEEEFEEE

Filename of malloc () call

0x00320fec

-20

0xbaadf00d

0x00000000

0xDDDDDDDD

0xFEEEFEEE

Line number of malloc () call

0x00320ff0

-16

0xbaadf00d

0x00000008

0xDDDDDDDD

0xFEEEFEEE

Number of bytes to malloc ()

0x00320ff4

-12

0xbaadf00d

0x00000001

0xDDDDDDDD

0xFEEEFEEE

Type (0=freed, 1=normal, 2=crt use, etc)

0x00320ff8

-8

0xbaadf00d

0x00000031

0xDDDDDDDD

0xFEEEFEEE

Request #, increases from 0

0x00320ffc

-4

0xbaadf00d

0xFDFDFDFD

0xDDDDDDDD

0xFEEEFEEE

No Mans Land

0x00321000

+0

0xbaadf00d

0xCDCDCDCD

0xDDDDDDDD

0xFEEEFEEE

The 8 bytes you wanted

0x00321004

+4

0xbaadf00d

0xCDCDCDCD

0xDDDDDDDD

0xFEEEFEEE

The 8 bytes you wanted

0x00321008

+8

0xbaadf00d

0xFDFDFDFD

0xDDDDDDDD

0xFEEEFEEE

No Mans Land

0x0032100c

+12

0xbaadf00d

0xbaadf00d

0xDDDDDDDD

0xFEEEFEEE

Win32 heap allocations is rounded up to bytes

0x00321010

+16

0xABABABAB

0xABABABAB

0xABABABAB

0xFEEEFEEE

Win32 Heap Bookkeeping

0x00321014

+20

0xABABABAB

0xABABABAB

0xABABABAB

0xFEEEFEEE

Win32 Heap Bookkeeping

0x00321018

+24

0x00000010

0x00000010

0x00000010

0xFEEEFEEE

Win32 Heap Bookkeeping

0x0032101c

+28

0x00000000

0x00000000

0x00000000

0xFEEEFEEE

Win32 Heap Bookkeeping

0x00321020

+32

0x00090051

0x00090051

0x00090051

0xFEEEFEEE

Win32 Heap Bookkeeping

0x00321024

+36

0xfeee0400

0xfeee0400

0xfeee0400

0xFEEEFEEE

Win32 Heap Bookkeeping

0x00321028

+40

0x00320400

0x00320400

0x00320400

0xFEEEFEEE

Win32 Heap Bookkeeping

0x0032102c

+44

0x00320400

0x00320400

0x00320400

0xFEEEFEEE

Win32 Heap Bookkeeping

[old article moved] In-depth analysis of the Win32 CRT debug heap

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.