!heap
La extensión !heap muestra información sobre el uso del montón, controla los puntos de interrupción en el administrador de montón, detecta bloques de montón filtrados, busca bloques de montón o muestra información sobre el montón de la página.
Esta extensión admite el montón de segmento y el montón NT. Utilice !heap sin ningún parámetro para enumerar todos los montones y su tipo.
!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] -?
!heap -triage [Handle | Address]
Parámetros de montón de segmento y NT
Estos parámetros funcionan con los montones de Segmento y NT.
-s
Especifica que se está solicitando información resumida. Si se omiten SummaryOptions y StatHeapAddress, se mostrará información resumida de todos los montones asociados al proceso actual.
SummaryOptions
Puede ser combinación de las siguientes opciones. SummaryOptions no distingue entre mayúsculas y minúsculas. Escriba !heap -s -? para obtener información adicional.
Opción | Efecto |
---|---|
-v |
Verifica todos los bloques de datos. |
-b BucketSize |
Especifica el tamaño del cubo. El valor predeterminado es 1024 bits. |
-d DumpBlockSize |
Especifica el tamaño del cubo. |
-a |
Vuelca todos los bloques del montón. |
-c |
Especifica que se debe mostrar el contenido de cada bloque. |
-triage [Handle | Address]
Hace que el depurador busque automáticamente errores en los montones de un proceso. Si se especifica un identificador de montón como argumento, se examina ese montón; de lo contrario, se buscan todos los montones en busca de uno que contenga la dirección determinada y, si se encuentra uno, se examina. El uso de -triage es la única forma de validar la corrupción del montón de baja fragmentación (LFH).
-x [-v]
Hace que el depurador busque el bloque de montón que contiene la dirección especificada. Si se añade -v, el comando buscará en todo el espacio de memoria virtual del proceso actual punteros a este bloque de montón.
-l
Hace que el depurador detecte los bloques de montón filtrados.
-i Address -h HeapAddress
Muestra información sobre el montón especificado.
Address
Especifica la dirección que se va a buscar.
-?
Muestra un breve texto de ayuda para esta extensión en la ventana de comando del depurador. Utilice !heap -? para ayuda genérica y !heap -p -? para ayuda del montón de páginas.
Parámetros del montón NT
Estos parámetros solo funcionan con el montón NT.
HeapOptions
Puede ser combinación de las siguientes opciones. Los valores de HeapOptions distinguen entre mayúsculas y minúsculas.
Opción | Efecto |
---|---|
-v |
Hace que el depurador valide el montón especificado.
Nota Esta opción no detecta la corrupción del montón de baja fragmentación (LFH). En su lugar, use -triage.
|
-a |
Hace que la visualización incluya toda la información del montón especificado. El tamaño, en este caso, se redondea a la granularidad del montón. (Ejecutar !heap con la opción -a equivale a ejecutarlo con las tres opciones -h -f -m, lo que puede llevar mucho tiempo). |
-h |
Hace que la visualización incluya todas las entradas que no sean LFH para el montón especificado. |
-hl |
Hace que la visualización incluya todas las entradas del montón o montones especificados, incluidas las entradas LFH. |
-f |
Hace que la visualización incluya todas las entradas de la lista de libres para el montón especificado. |
-m |
Hace que la visualización incluya todas las entradas de segmento para el montón especificado. |
-t |
Hace que la visualización incluya la información de etiquetas del montón especificado. |
-T |
Hace que la visualización incluya las entradas de pseudoetiquetas del montón especificado. |
-g |
Hace que la visualización incluya la información de la etiqueta global. Las etiquetas globales se asocian a cada asignación no etiquetada. |
-s |
Hace que la visualización incluya información resumida del montón especificado. |
-k |
(Solo objetivos basados en x86) Hace que la visualización incluya el seguimiento regresivo de pila asociado a cada entrada. |
ValidationOptions
Puede ser cualquiera de las siguientes opciones. ValidationOptions distingue entre mayúsculas y minúsculas.
Opción | Efecto |
---|---|
-D |
Deshabilita la validación en llamada para el montón especificado. |
-E |
Habilita la validación en llamada para el montón especificado. |
-d |
Deshabilita la comprobación para el montón especificado. |
-e |
Habilita la comprobación para el montón especificado. |
-i Heap Address o HeapAddress
Muestra información sobre el montón especificado.
BreakAddress
Especifica la dirección de un bloque en el que se debe establecer o eliminar un punto de interrupción.
-b
Hace que el depurador cree un punto de interrupción condicional en el administrador de montón. La opción -b puede ir seguida de alloc, realloc, o free; esto especifica si el punto de ruptura se activará al asignar, reasignar o liberar memoria. Si se utiliza BreakAddress para especificar la dirección del bloque, se puede omitir el tipo de punto de ruptura. Si se utiliza Heap para especificar la dirección del montón o el índice del montón, debe incluirse el tipo, así como el parámetro Tag.
Tag
Especifica el nombre de la etiqueta dentro del montón.
-B
Hace que el depurador elimine un punto de interrupción condicional del administrador de montón. Debe especificarse el tipo de punto de ruptura (alloc, realloc, o free), que debe ser el mismo que el utilizado con la opción -b.
StatHeapAddress
Especifica la dirección del montón. Si es 0 o se omite, se mostrarán todos los montones asociados al proceso actual.
-p
Especifica que se está solicitando información sobre el montón de páginas. Si se utiliza sin ningún PageHeapOptions, se mostrarán todos los montones de páginas.
PageHeapOptions
Puede ser cualquiera de las siguientes opciones. PageHeapOptions distingue entre mayúsculas y minúsculas. Si no se especifica ninguna opción, se mostrarán todos los posibles identificadores del montón de páginas.
Opción | Efecto |
---|---|
-h Handle |
Hace que el depurador muestre información detallada sobre un montón de páginas con el identificador Handle. |
-a Address |
Hace que el depurador busque el montón de páginas cuyo bloque contiene Address. Se incluirán todos los detalles de cómo se relaciona esta dirección con los bloques del montón de páginas completas, como si esta dirección forma parte de un montón de páginas, su desplazamiento dentro del bloque y si el bloque está asignado o se liberó. Los seguimientos de pila se incluyen siempre que están disponibles. Cuando se utiliza esta opción, el tamaño se muestra en múltiplos de la granularidad de asignación del montón. |
-t[c|s] [Traces] |
Hace que el depurador muestre los seguimientos recopilados de los usuarios del montón pesado. Traces especifica el número de seguimientos que se va a mostrar; el valor predeterminado es cuatro. Si hay más seguimientos que el número especificado, se mostrarán los seguimientos más antiguos. Si se utiliza -t o -tc, los seguimientos se ordenan por uso de recuento. Si se utiliza -ts, los seguimientos se ordenan por tamaño. (Las opciones -tc y -ts solo son compatibles con Windows XP; la opción -t solo es compatible con Windows XP y versiones anteriores de Windows). |
-fi [Traces] |
Hace que el depurador muestre los seguimientos de inyección de errores más recientes. Traces especifica la cantidad que se va a mostrar; el valor predeterminado es 4. |
-all |
Hace que el depurador muestre información detallada sobre todos los montones de páginas. |
-? |
Hace que el depurador muestre la ayuda del montón de páginas, incluido un diagrama de los bloques de montón. (Estos diagramas también pueden verse en la siguiente sección de Observaciones). |
Antes de que pueda utilizar cualquier comando de extensión !heap -p, el montón de páginas debe estar habilitado para su proceso de destino. Consulte los detalles en la siguiente sección de Observaciones.
-srch
Busca en todos los montones el patrón determinado.
Pattern
Especifica un patrón por el que buscar.
Size
Puede ser cualquiera de las siguientes opciones. Especifica el tamaño del patrón. El '-' es obligatorio.
Opción | Efecto |
---|---|
-b |
El patrón tiene un tamaño de un BYTE. |
-w |
El patrón tiene un tamaño de un WORD. |
-d |
El patrón tiene un tamaño de un DWORD. |
-q |
El patrón tiene un tamaño de un QWORD. |
Si no se especifica ninguno de los anteriores, se supone que el patrón tiene el mismo tamaño que el puntero de la máquina.
-flt
Limita la visualización para incluir solo las asignaciones de montones con un tamaño o intervalo de tamaño especificado.
FilterOptions
Puede ser cualquiera de las siguientes opciones. FilterOptions distingue entre mayúsculas y minúsculas.
Opción | Efecto |
---|---|
s Size |
Limita la visualización para incluir solo los montones de un tamaño. |
r SizeMin SizeMax |
Limita la visualización para incluir solo los montones dentro del intervalo de tamaño especificado. |
Nota:
En versiones posteriores de las opciones de !heap, como -flt
puede que ya no estén presentes. Use la ayuda de la línea de comandos para confirmar las opciones disponibles.
-stat
Muestra las estadísticas de uso del montón especificado.
-h Handle
Hace que solo se muestren las estadísticas de uso del montón en Handle. Si Handle es 0 o se omite, se mostrarán las estadísticas de uso de todos los montones.
-grp GroupBy
Reordena la visualización según lo especificado por GroupBy. Las opciones de GroupBy se encuentran en la tabla siguiente.
Opción | Efecto |
---|---|
A |
Muestra las estadísticas de uso según el tamaño de la asignación. |
B |
Muestra las estadísticas de uso según el recuento de bloques. |
S |
Muestra las estadísticas de uso según el tamaño total de cada asignación. |
MaxDisplay
Limita la salida a solo el número de líneas de MaxDisplay.
DLL
Windows XP y versiones posteriores |
Ext.dll Exts.dll |
Información adicional
Para obtener información sobre los montones, consulte los siguientes recursos:
Libro: Microsoft Windows Internals de Mark Russinovich y David Solomon.
Ejemplo 11: Habilitación de la verificación del montón de páginas
Ejemplo 12: Utilizar la verificación del montón de páginas para encontrar un error
Para obtener más información sobre el uso del registrador de procesos de memoria de montón, consulte Ejemplo 11: Iniciar una sesión privada de seguimiento
Comentarios
Este comando de extensión puede utilizarse para realizar diversas tareas.
El comando estándar !heap se utiliza para mostrar la información del montón del proceso actual. (Solo debe utilizarse para procesos en modo de usuario. El comando de extensión !pool debe utilizarse para los procesos del sistema).
Los comandos !heap -b y !heap -B se utilizan para crear y eliminar puntos de interrupción condicionales en el administrador del montón.
El comando !heap -l detecta los bloques de montón filtrados. Utiliza un algoritmo de recolección de basura para detectar todos los bloques ocupados de los montones a los que no se hace referencia en ninguna parte del espacio de direcciones del proceso. En el caso de solicitudes muy grandes, puede tardar unos minutos en completarse. Este comando solo está disponible en Windows XP y versiones posteriores de Windows.
El comando !heap -x busca un bloque de montón que contenga una dirección determinada. Si se usa la opción -v, este comando buscará además en todo el espacio de memoria virtual del proceso actual punteros a este bloque de montón. Este comando solo está disponible en Windows XP y versiones posteriores de Windows.
El comando !heap -p muestra varias formas de información sobre el montón de páginas. Antes de utilizar !heap -p, debe habilitar el montón de páginas para el proceso de destino. Esto se hace a través de la utilidad Global Flags (gflags.exe). Para ello, inicie la utilidad, rellene el nombre de la aplicación de destino en el cuadro de texto Image File Name (Nombre del archivo de imagen), seleccione Image File Options (Opciones de archivo de imagen) y Enable page heap (Habilitar montón de páginas),y seleccione Apply (Aplicar). Como alternativa, puede iniciar la utilidad Global Flags desde una ventana de símbolo del sistema escribiendo gflags /i xxx.exe +hpa, donde xxx.exe es el nombre de la aplicación de destino.
Los comandos !heap -p -t[c|s] no son compatibles más allá de Windows XP. Utilice la herramienta UMDH proporcionada con el paquete de depurador para obtener resultados similares.
El comando !heap -srch muestra las entradas del montón que contienen un determinado patrón especificado.
El comando !heap -flt limita la visualización a solo las asignaciones de montón de un tamaño especificado.
El comando !heap -stat muestra las estadísticas de uso del montón.
Este es un ejemplo de un comando !heap estándar:
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.
Este es un ejemplo de un comando !heap -I:
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.
La tabla de este ejemplo contiene las 21 fugas encontradas.
Este es un ejemplo de un comando !heap -x:
0:011> !heap 002057b8 -x
## Entry User Heap Segment Size PrevSize Flags
002057a8 002057b0 00170000 00170640 58 58 busy extra
Este es un ejemplo de un comando !heap -x -v:
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),
En este ejemplo, hay un puntero a este bloque de montón en la dirección 0x00205990.
Este es un ejemplo de un comando !heap -flt s:
0:001>!heap -flt s 0x50
Esto mostrará todas las asignaciones de tamaño 0x50.
Este es un ejemplo de un comando !heap -flt r:
0:001>!heap -flt r 0x50 0x80
Esto mostrará cada asignación cuyo tamaño esté entre 0x50 y 0x7F.
Este es un ejemplo de un comando !heap -srch.
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'
Los siguientes diagramas muestran la disposición de los bloques de montón.
Bloque de montón de página ligera; asignado:
+-----+---------------+---+
| | | |
+-----+---------------+---+
^ ^ ^
| | 8 suffix bytes (filled with 0xA0)
| User allocation (filled with E0 if zeroing not requested)
Block header (starts with 0xABCDAAAA and ends with 0xDCBAAAAA)
Bloque de montón de página ligera; libre:
+-----+---------------+---+
| | | |
+-----+---------------+---+
^ ^ ^
| | 8 suffix bytes (filled with 0xA0)
| User allocation (filled with F0 bytes)
Block header (starts with 0xABCDAAA9 and ends with 0xDCBAAA9)
Bloque de montón de página completa; asignado:
+-----+---------+---+-------
| | | | ... N/A page
+-----+---------+---+-------
^ ^ ^
| | 0-7 suffix bytes (filled with 0xD0)
| User allocation (if zeroing not requested, filled
with C0)
Block header (starts with 0xABCDBBBB and ends with 0xDCBABBBB)
Bloque de montón de página completa; libre:
+-----+---------+---+-------
| | | | ... 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)
Para ver el rastro de pila de la asignación o la liberación de un bloque de montón o de un bloque de montón de página completa, utilice dt DPH_BLOCK_INFORMATION con la dirección de encabezado, seguido de dds con el campo StackTrace del bloque.