Debugging Tools for Windows
!heap
The !heap extension displays heap usage information, controls breakpoints in the heap manager, detects leaked heap blocks, searches for heap blocks, or displays page heap information.
Syntax
Syntax in Windows 2000
!heap [HeapOptions] [ValidationOptions] [Heap]
!heap -b [{alloc|realloc|free} [Tag]] [Heap | BreakAddress]
!heap -B {alloc|realloc|free} [Heap | BreakAddress]
!heap -p PageHeapOptions
!heap [-p] -?
Syntax in Windows XP and later
!heap [HeapOptions] [ValidationOptions] [Heap]
!heap -b [{alloc|realloc|free} [Tag]] [Heap | BreakAddress]
!heap -B {alloc|realloc|free} [Heap | BreakAddress]
!heap -l
!heap -s [SummaryOptions] [StatHeapAddress]
!heap -i HeapAddress
!heap -x [-v] Address
!heap -p [PageHeapOptions]
!heap -srch [Size] Pattern
!heap -flt FilterOptions
!heap -stat [-h Handle [-grp GroupBy [MaxDisplay]]]
!heap [-p] -?
Parameters
- Heap
- Specifies either a heap index number or a heap address. The default is 1; this specifies the process heap. Zero causes the command to display information about all heaps in the process. Omitting Heap gives a concise list of all heaps in the process.
- HeapOptions
- Can be any combination of the following options. The HeapOptions values are case-sensitive.
| Option | Effect |
| -v | Causes the debugger to validate the specified heap. |
| -a | Causes the display to include all information for the specified heap. Size, in this case, is rounded up to the heap granularity. (Running !heap with the –a option is equivalent to running it with the three options -h -f -m, which can take a long time.) |
| -h | Causes the display to include all entries for the specified heap. |
| -f | Causes the display to include all the free list entries for the specified heap. |
| -m | Causes the display to include all the segment entries for the specified heap. |
| -t | Causes the display to include the tag information for the specified heap. |
| -T | Causes the display to include the pseudo-tag entries for the specified heap. |
| -g | Causes the display to include the global tag information. Global tags are associated with each untagged allocation. |
| -s | Causes the display to include summary information for the specified heap. |
| -k | (x86-based targets only) Causes the display to include the stack backtrace associated with each entry. |
- ValidationOptions
- Can be any single one of the following options. The ValidationOptions are case-sensitive.
| Option | Effect |
| -D | Disables validate-on-call for the specified heap. |
| -E | Enables validate-on-call for the specified heap. |
| -d | Disables heap checking for the specified heap. |
| -e | Enables heap checking for the specified heap. |
- BreakAddress
- Specifies the address of a block where a breakpoint is to be set or removed.
- -b
- Causes the debugger to create a conditional breakpoint in the heap manager. The -b option can be followed by alloc, realloc, or free; this specifies whether the breakpoint will be activated by allocating, reallocating, or freeing memory. If BreakAddress is used to specify the address of the block, the breakpoint type can be omitted. If Heap is used to specify the heap address or heap index, the type must be included, as well as the Tag parameter.
- Tag
- Specifies the tag name within the heap.
- -B
- Causes the debugger to remove a conditional breakpoint from the heap manager. The breakpoint type (alloc, realloc, or free) must be specified, and must be the same as that used with the -b option.
- -l
- (Windows XP and later) Causes the debugger to detect leaked heap blocks.
- -s
- (Windows XP and later) Specifies that summary information is being requested. If SummaryOptions and StatHeapAddress are omitted, then summary information is displayed for all heaps associated with the current process.
- SummaryOptions
- (Windows XP and later) Can be any combination of the following options. The SummaryOptions are not case-sensitive.
| Option | Effect |
| -v | Verifies all data blocks. |
| -b BucketSize | Specifies the bucket size. The default is 1024 bits. |
| -d DumpBlockSize | Specifies the bucket size. |
| -a |
| -c | Specifies that the contents of each block should be displayed. |
- StatHeapAddress
- (Windows XP and later) Specifies the address of the heap. If this is 0 or omitted, all heaps associated with the current process are displayed.
- -i Heap
- (Windows XP and later) Displays information about the specified Heap.
- -x [-v]
- (Windows XP and later) Causes the debugger to search for the heap block containing the specified address. If -v is added, the command will search the entire virtual memory space of the current process for pointers to this heap block.
- Address
- (Windows XP and later) Specifies the address to search for.
- -p
- Specifies that page heap information is being requested. If this is used without any PageHeapOptions, all page heaps will be displayed.
- PageHeapOptions
- Can be any single one of the following options. The PageHeapOptions are case-sensitive. If no options are specified, then all possible page heap handles will be displayed.
| Option | Effect |
| -h Handle | Causes the debugger to display detailed information about a page heap with handle Handle. |
| -a Address | Causes the debugger to find the page heap whose block contains Address. Full details of how this address relates to full-page heap blocks will be included, such as whether this address is part of a page heap, its offset inside the block, and whether the block is allocated or was freed. Stack traces are included whenever available. When using this option, size is displayed in multiples of the heap allocation granularity. |
| -t[c|s] [Traces] | Causes the debugger to display the collected traces of the heavy heap users. Traces specifies the number of traces to display; the default is four. If there are more traces than the specified number, the earliest traces are displayed. If -t or -tc is used, the traces are sorted by count usage. If -ts is used, the traces are sorted by size. (The -tc and -ts options are supported in Windows XP only; the -t option is supported only in Windows XP and earlier versions of Windows.) |
| -fi [Traces] | (Windows XP and later) Causes the debugger to display the most recent fault injection traces. Traces specifies the quantity to be displayed; the default is 4. |
| -all | (Windows XP and later) Causes the debugger to display detailed information about all page heaps. |
| -? | Causes the debugger to display page heap help, including a diagram of heap blocks. (These diagrams can also be seen in the following Comments section.) |
Before you can use any !heap -p extension command, the page heap must be enabled for your target process. See details in the following Comments section.
- -srch
- (Windows XP and later) Scans all heaps for the given pattern.
- Pattern
- (Windows XP and later) Specifies a pattern for which to look.
- Size
- (Windows XP and later) Can be any single one of the following options. This specifies the size of the pattern. The '-' is required.
| Option | Effect |
| -b | The pattern is one BYTE in size. |
| -w | The pattern is one WORD in size. |
| -d | The pattern is one DWORD in size. |
| -q | The pattern is one QWORD in size. |
If none of the above are specified, then the pattern is assumed to be of the same size as the machine pointer.
- -flt
- (Windows XP and later) Limits the display to include only heaps with the specified size or size range.
- FilterOptions
- (Windows XP and later) Can be any single one of the following options. The FilterOptions are case-sensitive.
| Option | Effect |
| s Size | Limits the display to include only heaps of the specified size. |
| r SizeMin SizeMax | Limits the display to include only heaps within the specified size range. |
- -stat
- (Windows XP and later) Displays usage statistics for the specified heap.
- -h Handle
- (Windows XP and later) Causes usage statistics for only the heap at Handle to be displayed. If Handle is 0 or omitted, then usage statistics for all heaps are displayed.
- -grp GroupBy
- (Windows XP and later) Reorders the display as specified by GroupBy. The options for GroupBy can be found in the following table.
| Option | Effect |
| A | Displays the usage statistics according to allocation size. |
| B | Displays the usage statistics according to block count. |
| S | Displays the usage statistics according to the total size of each allocation. |
- MaxDisplay
- (Windows XP and later) Limits the output to only MaxDisplay number of lines.
- -?
- Displays some brief Help text for this extension in the Debugger Command window. Use !heap -? for generic help, and !heap -p -? for page heap help.
DLL
| Windows 2000 | Ext.dll Kdextx86.dll Ntsdexts.dll |
| Windows XP and later | Ext.dll Exts.dll |
Comments
This extension command can be used to perform a variety of tasks.
The standard !heap command is used to display heap information for the current process. (This should be used only for user-mode processes. The !pool extension command should be used for system processes.)
The !heap -b and !heap -B commands are used to create and delete conditional breakpoints in the heap manager.
The !heap -l command detects leaked heap blocks. It uses a garbage collector algorithm to detect all busy blocks from the heaps that are not referenced anywhere in the process address space. For huge applications, it can take a few minutes to complete. This command is only available in Windows XP and later versions of Windows.
The !heap -x command searches for a heap block containing a given address. If the -v option is used, this command will additionally search the entire virtual memory space of the current process for pointers to this heap block. This command is only available in Windows XP and later versions of Windows.
The !heap -p command displays various forms of page heap information. Before using !heap -p, you must enable the page heap for the target process. This is done through the Global Flags (gflags.exe) utility. To do this, start the utility, fill in the name of the target application in the Image File Name text box, select Image File Options and Enable page heap, and click Apply. Alternatively, you can start the Global Flags utility from a Command Prompt window by typing gflags /i xxx.exe +hpa, where xxx.exe is the name of the target application.
The !heap -p -t[c|s] commands are not supported beyond Windows XP. Use the UMDH tool provided with the debugger package to obtain similar results.
The !heap -srch command displays those heap entries that contain a certain specified pattern. This command is only available in Windows XP and later versions of Windows.
The !heap -flt command limits the display to only heap allocations of a specified size. This command is only available in Windows XP and later versions of Windows.
The !heap -stat command displays heap usage statistics. This command is only available in Windows XP and later versions of Windows.
Here is an example of the standard !heap command:
0:000> !ntsdexts.heap -a
Index Address Name Debugging options enabled
1: 00250000
Segment at 00250000 to 00350000 (00056000 bytes committed)
Flags: 50000062
ForceFlags: 40000060
Granularity: 8 bytes
Segment Reserve: 00100000
Segment Commit: 00004000
DeCommit Block Thres:00000400
DeCommit Total Thres:00002000
Total Free Size: 000003be
Max. Allocation Size:7ffddfff
Lock Variable at: 00250b54
Next TagIndex: 0012
Maximum TagIndex: 07ff
Tag Entries: 00350000
PsuedoTag Entries: 00250548
Virtual Alloc List: 00250050
UCR FreeList: 002504d8
128-bit bitmap of free lists
FreeList Usage: 00000014 00000000 00000000 00000000
Free Free
List List
# Head Blink Flink
FreeList[ 00 ] at 002500b8: 002a4378 . 002a4378
0x02 - HEAP_ENTRY_EXTRA_PRESENT
0x04 - HEAP_ENTRY_FILL_PATTERN
Entry Prev Cur 0x10 - HEAP_ENTRY_LAST_ENTRY
Address Size Size flags
002a4370: 00098 . 01c90 [14] - free
FreeList[ 02 ] at 002500c8: 0025cb30 . 002527b8
002527b0: 00058 . 00010 [04] - free
0025cb28: 00088 . 00010 [04] - free
FreeList[ 04 ] at 002500d8: 00269a08 . 0026e530
0026e528: 00038 . 00020 [04] - free
0026a4d0: 00038 . 00020 [06] - free
0026f9b8: 00038 . 00020 [04] - free
0025cda0: 00030 . 00020 [06] - free
00272660: 00038 . 00020 [04] - free
0026ab60: 00038 . 00020 [06] - free
00269f20: 00038 . 00020 [06] - free
00299818: 00038 . 00020 [04] - free
0026c028: 00038 . 00020 [06] - free
00269a00: 00038 . 00020 [46] - free
Segment00 at 00250b90:
Flags: 00000000
Base: 00250000
First Entry: 00250bc8
Last Entry: 00350000
Total Pages: 00000080
Total UnCommit: 00000055
Largest UnCommit:000aa000
UnCommitted Ranges: (1)
002a6000: 000aa000
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)
00250c08: 00040 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00250c68: 00060 . 00028 [07] - busy (10), tail fill (NTDLL!LDR Database)
00250c90: 00028 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00250cf0: 00060 . 00050 [07] - busy (38), tail fill (Objects= 80)
00250d40: 00050 . 00048 [07] - busy (2e), tail fill (NTDLL!LDR Database)
00250d88: 00048 . 00c10 [07] - busy (bf4), tail fill (Objects>1024)
00251998: 00c10 . 00030 [07] - busy (12), tail fill (NTDLL!LDR Database)
...
002525c0: 00030 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
00252620: 00060 . 00050 [07] - busy (38), tail fill (NTDLL!LDR Database)
00252670: 00050 . 00040 [07] - busy (22), tail fill (NTDLL!CSRSS Client)
002526b0: 00040 . 00040 [07] - busy (24), tail fill (Objects= 64)
002526f0: 00040 . 00040 [07] - busy (24), tail fill (Objects= 64)
00252730: 00040 . 00028 [07] - busy (10), tail fill (Objects= 40)
00252758: 00028 . 00058 [07] - busy (3c), tail fill (Objects= 88)
002527b0: 00058 . 00010 [04] free fill
002527c0: 00010 . 00058 [07] - busy (3c), tail fill (NTDLL!LDR Database)
00252818: 00058 . 002d0 [07] - busy (2b8), tail fill (Objects= 720)
00252ae8: 002d0 . 00330 [07] - busy (314), tail fill (Objects= 816)
00252e18: 00330 . 00330 [07] - busy (314), tail fill (Objects= 816)
00253148: 00330 . 002a8 [07] - busy (28c), tail fill (NTDLL!LocalAtom)
002533f0: 002a8 . 00030 [07] - busy (18), tail fill (NTDLL!LocalAtom)
00253420: 00030 . 00030 [07] - busy (18), tail fill (NTDLL!LocalAtom)
00253450: 00030 . 00098 [07] - busy (7c), tail fill (BASEDLL!LMEM)
002534e8: 00098 . 00060 [07] - busy (44), tail fill (BASEDLL!TMP)
00253548: 00060 . 00020 [07] - busy (1), tail fill (Objects= 32)
00253568: 00020 . 00028 [07] - busy (10), tail fill (Objects= 40)
00253590: 00028 . 00030 [07] - busy (16), tail fill (Objects= 48)
...
0025ccb8: 00038 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
0025cd18: 00060 . 00058 [07] - busy (3c), tail fill (NTDLL!LDR Database)
0025cd70: 00058 . 00030 [07] - busy (18), tail fill (NTDLL!LDR Database)
0025cda0: 00030 . 00020 [06] free fill (NTDLL!Temporary)
0025cdc0: 00020 . 00258 [07] - busy (23c), tail fill (Objects= 600)
0025d018: 00258 . 01018 [07] - busy (1000), tail fill (Objects>1024)
0025e030: 01018 . 00060 [07] - busy (48), tail fill (NTDLL!LDR Database)
...
002a4190: 00028 . 00118 [07] - busy (100), tail fill (BASEDLL!GMEM)
002a42a8: 00118 . 00030 [07] - busy (18), tail fill (Objects= 48)
002a42d8: 00030 . 00098 [07] - busy (7c), tail fill (Objects= 152)
002a4370: 00098 . 01c90 [14] free fill
002a6000: 000aa000 - uncommitted bytes.
Here is an example of the !heap -l command:
1:0:011> !heap -l
1:Heap 00170000
Heap 00280000
Heap 00520000
Heap 00b50000
Heap 00c60000
Heap 01420000
Heap 01550000
Heap 016d0000
Heap 019b0000
Heap 01b40000
Scanning VM ...
Entry User Heap Segment Size PrevSize Flags
----------------------------------------------------------------------
001b2958 001b2960 00170000 00000000 40 18 busy extra
001b9cb0 001b9cb8 00170000 00000000 80 300 busy extra
001ba208 001ba210 00170000 00000000 80 78 busy extra
001cbc90 001cbc98 00170000 00000000 e0 48 busy extra
001cbd70 001cbd78 00170000 00000000 d8 e0 busy extra
001cbe90 001cbe98 00170000 00000000 68 48 busy extra
001cbef8 001cbf00 00170000 00000000 58 68 busy extra
001cc078 001cc080 00170000 00000000 f8 128 busy extra
001cc360 001cc368 00170000 00000000 80 50 busy extra
001cc3e0 001cc3e8 00170000 00000000 58 80 busy extra
001fe550 001fe558 00170000 00000000 150 278 busy extra
001fe6e8 001fe6f0 00170000 00000000 48 48 busy extra
002057a8 002057b0 00170000 00000000 58 58 busy extra
00205800 00205808 00170000 00000000 48 58 busy extra
002058b8 002058c0 00170000 00000000 58 70 busy extra
00205910 00205918 00170000 00000000 48 58 busy extra
00205958 00205960 00170000 00000000 90 48 busy extra
00246970 00246978 00170000 00000000 60 88 busy extra
00251168 00251170 00170000 00000000 78 d0 busy extra user_flag
00527730 00527738 00520000 00000000 40 40 busy extra
00527920 00527928 00520000 00000000 40 80 busy extra
21 leaks detected.
The table in this example contains all 21 leaks found.
Here is an example of the !heap -x command:
0:011> !heap 002057b8 -x
Entry User Heap Segment Size PrevSize Flags
----------------------------------------------------------------------
002057a8 002057b0 00170000 00170640 58 58 busy extra
Here is an example of the !heap -x -v command:
1:0:011> !heap 002057b8 -x -v
1:Entry User Heap Segment Size PrevSize Flags
----------------------------------------------------------------------
002057a8 002057b0 00170000 00170640 58 58 busy extra
Search VM for address range 002057a8 - 002057ff : 00205990 (002057d0),
In this example, there is a pointer to this heap block at address 0x00205990.
Here is an example of the !heap -flt s command:
0:001>!heap -flt s 0x50
This will display all of the allocations of size 0x50.
Here is an example of the !heap -flt r command:
0:001>!heap -flt r 0x50 0x80
This will display each allocation whose size is between 0x50 and 0x7F.
Here is an example of the !heap -srch command.
0:001> !heap -srch 77176934
_HEAP @ 00090000
in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
00099A48: 0018 : 0005 [01] - 00099A50 (000000B8) - (busy)
ole32!CALLFRAME_CACHE<INTERFACE_HELPER_CLSID>::`vftable'
_HEAP @ 00090000
in HEAP_ENTRY: Size : Prev Flags - UserPtr UserSize - state
00099B58: 0018 : 0005 [01] - 00099B60 (000000B8) - (busy)
ole32!CALLFRAME_CACHE<INTERFACE_HELPER_CLSID>::`vftable'
The following diagrams show the arrangement of heap blocks. These are valid in Windows 2000 (Service Pack 1 and later), Windows XP, and later versions of Windows.
Light page heap block — allocated:
+-----+---------------+---+
| | | |
+-----+---------------+---+
^ ^ ^
| | 8 suffix bytes (filled with 0xA0)
| User allocation (filled with E0 if zeroing not requested)
Block header (starts with 0xABCDAAAA and ends with 0xDCBAAAAA)
Light page heap block — freed:
+-----+---------------+---+
| | | |
+-----+---------------+---+
^ ^ ^
| | 8 suffix bytes (filled with 0xA0)
| User allocation (filled with F0 bytes)
Block header (starts with 0xABCDAAA9 and ends with 0xDCBAAA9)
Full page heap block — allocated:
+-----+---------+---+-------
| | | | ... N/A page
+-----+---------+---+-------
^ ^ ^
| | 0-7 suffix bytes (filled with 0xD0)
| User allocation (if zeroing not requested, filled
with E0 in Windows 2000 and C0 in Windows XP)
Block header (starts with 0xABCDBBBB and ends with 0xDCBABBBB)
Full page heap block — freed:
+-----+---------+---+-------
| | | | ... N/A page
+-----+---------+---+-------
^ ^ ^
| | 0-7 suffix bytes (filled with 0xD0)
| User allocation (filled with F0 bytes)
Block header (starts with 0xABCDBBA and ends with 0xDCBABBBA)
To see the stack trace of the allocation or the freeing of a heap block or full page heap block in Windows 2000, use dds (Display Words and Symbols) with the header address.
To see the stack trace of the allocation or the freeing of a heap block or full page heap block in Windows XP or a later version of Windows, use dt DPH_BLOCK_INFORMATION with the header address, followed by dds with the block's StackTrace field.
Full page heap blocks in Windows 2000 reside at the beginning of the page containing the user allocation, or at the previous page.
Additional Information
For information about heaps, see the Microsoft Windows SDK documentation, the Windows Driver Kit (WDK) documentation, and Microsoft Windows Internals by Mark Russinovich and David Solomon.
Build machine: CAPEBUILD