windowsdebuggingheap-memorywindbgdmp

What do the 'size' numbers mean in the windbg !heap output?


I see output like this in my DMP file:

Heap entries for Segment00 in Heap 00150000
    00150640: 00640 . 00040 [01] - busy (40)
    00150680: 00040 . 01808 [01] - busy (1800)
    00151e88: 01808 . 00210 [01] - busy (208)
    00152098: 00210 . 00228 [00]
    001522c0: 00228 . 00030 [01] - busy (22)
    001522f0: 00030 . 00018 [01] - busy (10)
    00152308: 00018 . 00048 [01] - busy (3c)

The WinDbg docs say this:

    Heap entries for Segment00 in Heap 250000
                        0x01 - HEAP_ENTRY_BUSY            
                        0x02 - HEAP_ENTRY_EXTRA_PRESENT   
                        0x04 - HEAP_ENTRY_FILL_PATTERN    
                        0x08 - HEAP_ENTRY_VIRTUAL_ALLOC   
                        0x10 - HEAP_ENTRY_LAST_ENTRY      
                        0x20 - HEAP_ENTRY_SETTABLE_FLAG1  
                        0x40 - HEAP_ENTRY_SETTABLE_FLAG2  
Entry     Prev    Cur   0x80 - HEAP_ENTRY_SETTABLE_FLAG3  

Address   Size    Size  flags       (Bytes used)    (Tag name)
00250000: 00000 . 00b90 [01] - busy (b90)
00250b90: 00b90 . 00038 [01] - busy (38) 
00250bc8: 00038 . 00040 [07] - busy (24), tail fill (NTDLL!LDR Database)

The spacing is weird in the docs though. Does that mean 'entry address' and 'prev size' and 'cur size', or are the 'entry' 'prev' and 'cur' not for the line below?

What does 'prev size' and 'cur size' mean? Especially with regard to 'bytes used'. What is the difference between 'bytes used' and 'cur size'?


Solution

  • A heap segment is a continuous block of memory for a given heap. It is also a chain of heap entries.

    To walk a list of heap entries forward we can use the Cur Size as an offset to get to the next heap entry.

    To walk a list of heap entries backwards we can use the Prev Size as an offset to get to the beginning of the previous entry.

    Here (picture below) you can see the psize (previous size) and its relationship to the size (current size) for the entry just before it.

    Debugger Output Pic

    The Bytes used is calculated by subtracting the size from the the number of unused bytes at the end of this block that were not actually allocated. This allows you to determine the size of the allocation that was requested before rounding the requested size to allocation granularity.