First you need a little explanation ...
Heap vs virtual memory
The IMHO heap was invented because the graininess of VirtualAlloc() (which is 64 KB) was too wasteful for small amounts of data. If I look at the output !heap <address> , I see
Heap entries for Segment00 in Heap 00100000 address: psize . size flags state (requested size) 00100000: 00000 . 00588 [101] - busy (587)
See the size column, which contains 5 digits. This probably means the maximum usable heap record size
0:001> ? fffff Evaluate expression: 1048575 = 000fffff
approximately 1 MB. Above this size, it probably doesn't make sense to have heap grain, and you can use VirtualAlloc() directly. Or, not you, but the malloc() function solves this for you.
Exit error message
In your release you noticed two lines
Virtual Alloc List: 006500a0 Unable to read nt!_HEAP_VIRTUAL_ALLOC_ENTRY structure at 00750000
This is an indicator that there are parts in the heap that are actually being processed by VirtualAlloc() . However, WinDbg cannot find a data type for it:
0:001> dt nt!_HEAP_VIRTUAL_ALLOC_ENTRY Symbol nt!_HEAP_VIRTUAL_ALLOC_ENTRY not found.
There is no output !heap -s , so I created it on my machine (WinDbg 6.3.9600.16384):
0:001> !heap 00100000 -s LFH Key : 0x62502d13 Termination on corruption : ENABLED Heap Flags Reserv Commit Virt Free List UCR Virt Lock Fast (k) (k) (k) (k) length blocks cont. heap ----------------------------------------------------------------------------- Virtual block: 005b0000 - 005b0000 (size 00000000) Virtual block: 006b0000 - 006b0000 (size 00000000) ... Virtual block: 1fab0000 - 1fab0000 (size 00000000) 00100000 00000002 1024 204 1024 4 7 1 500 0 LFH -----------------------------------------------------------------------------
In my demo, I created ~ 500 blocks of 1 MB each. Please note that size 00000000 seems to be broken. However, if I use !address in the block, it will get the right size of the region (00100000):
0:001> !address 005b0000 ... Usage: Heap Base Address: 005b0000 End Address: 006b0000 Region Size: 00100000 State: 00001000 MEM_COMMIT Protect: 00000004 PAGE_READWRITE Type: 00020000 MEM_PRIVATE Allocation Base: 005b0000 Allocation Protect: 00000004 PAGE_READWRITE
What might the missing _HEAP_VIRTUAL_ALLOC_ENTRY look like?
0:001> dd 770000 L10 00770000 00870000 00670000 00000000 00000000 00770010 00100000 00100000 c8d50110 04000000 00770020 003df5a8 00870020 00000000 00000000 00770030 000ffc00 00000001 000000c1 fdfdfdfd
A value of 870000 at offset 0 is similar to FLink on the next block of memory and a value of 670000 at offset 4 a BLink on the previous one.
Offsets 10 and 14 match the size of the area.
0:001> ? 0n1023*0n1024 Evaluate expression: 1047552 = 000ffc00
At an offset of +30 - the size (here I highlighted blocks of 1023 kB).
FDFDFDFD is a well-known debugging magic number that indicates the absence of ground, so this is most likely the end of the structure.
Extract structure from XP dump
I have a dump available in Windows XP. See how nt!_HEAP_VIRTUAL_ALLOC_ENTRY :
0: kd> dt -r1 nt!_HEAP_VIRTUAL_ALLOC_ENTRY +0x000 Entry : _LIST_ENTRY +0x000 Flink : Ptr32 _LIST_ENTRY +0x004 Blink : Ptr32 _LIST_ENTRY +0x008 ExtraStuff : _HEAP_ENTRY_EXTRA +0x000 AllocatorBackTraceIndex : Uint2B +0x002 TagIndex : Uint2B +0x004 Settable : Uint4B +0x000 ZeroInit : Uint8B +0x010 CommitSize : Uint4B +0x014 ReserveSize : Uint4B +0x018 BusyBlock : _HEAP_ENTRY +0x000 Size : Uint2B +0x002 PreviousSize : Uint2B +0x000 SubSegmentCode : Ptr32 Void +0x004 SmallTagIndex : UChar +0x005 Flags : UChar +0x006 UnusedBytes : UChar +0x007 SegmentIndex : UChar
Conclusion
!heap seems to have problems for large blocks created by malloc() , which actually use VirtualAlloc() in this case. WinDbg cannot find the data type that it expects to match memory contents. Microsoft should probably fix this error.
The output statistics for the heap !address -summary seems reasonable.