win volcado memoria leer files dmp completa carpeta archivo analizar c++ debugging heap windbg crash-dumps

c++ - leer - ¿Análisis detallado del uso de la memoria del archivo de volcado de Windows?



volcado de memoria completa (3)

¿Cuántos basureros tienes ahora?

La forma correcta de rastrear la pérdida de memoria es hacer un buen uso de la regla de Fuga de memoria y manejo de DebugDiag.

Luego, cuando DebugDiag funciona en los nuevos volcados, puede decir más sobre el uso de la memoria.

Hemos recibido un archivo de volcado nativo (completo) de un cliente. Abrirlo en el depurador de Visual Studio (2005) muestra que tuvimos un bloqueo causado por una llamada de realloc que intentó asignar un bloque de ~ 10 MB. El archivo de volcado era inusualmente grande (1,5 GB, normalmente son más como 500 MB).

Por lo tanto, llegamos a la conclusión de que tenemos una "pérdida" de memoria o asignaciones fuera de control que agotaron completamente la memoria del proceso o, al menos, la fragmentaron de manera suficientemente significativa como para que el realloc falle. (Tenga en cuenta que esta asignación fue para una operación que asignó un búfer de registro y no nos sorprende que haya fallado aquí, porque 10MB de una sola vez sería una de las asignaciones más grandes que hacemos, aparte de algunos búferes muy grandes e inmutables: el problema probablemente no tenga nada que ver con esta asignación específica.)

Edit: Después del intercambio de comentarios con Lex Li a continuación, debo agregar: Esto no es reproducible para nosotros (en este momento). Es solo un volcado de clientes que muestra claramente el consumo de memoria fuera de control.

Pregunta principal:

Ahora tenemos un archivo de volcado, pero ¿cómo podemos localizar qué causó el uso excesivo de memoria?

Lo que hemos hecho hasta ahora:

Hemos utilizado la herramienta DebugDiag para analizar el archivo de volcado (el llamado analizador de presión de memoria), y esto es lo que obtuvimos:

Report for DumpFM...dmp Virtual Memory Summary ---------------------- Size of largest free VM block 62,23 MBytes Free memory fragmentation 81,30% Free Memory 332,87 MBytes (16,25% of Total Memory) Reserved Memory 0 Bytes (0,00% of Total Memory) Committed Memory 1,67 GBytes (83,75% of Total Memory) Total Memory 2,00 GBytes Largest free block at 0x00000000`04bc4000 Loaded Module Summary --------------------- Number of Modules 114 Modules Total reserved memory 0 Bytes Total committed memory 3,33 MBytes Thread Summary -------------- Number of Threads 56 Thread(s) Total reserved memory 0 Bytes Total committed memory 652,00 KBytes

Esto fue solo para obtener un poco de contexto. Cuál es más interesante que creo que es:

Heap Summary ------------ Number of heaps 26 Heaps Total reserved memory 1,64 GBytes Total committed memory 1,61 GBytes Top 10 heaps by reserved memory ------------------------------- 0x01040000 1,55 GBytes 0x00150000 64,06 MBytes 0x010d0000 15,31 MBytes ... Top 10 heaps by committed memory -------------------------------- 0x01040000 1,54 GBytes 0x00150000 55,17 MBytes 0x010d0000 6,25 MBytes ...

Ahora, mirando el montón 0x01040000 (1,5 GB) vemos:

Heap 5 - 0x01040000 ------------------- Heap Name msvcr80!_crtheap Heap Description This heap is used by msvcr80 Reserved memory 1,55 GBytes Committed memory 1,54 GBytes (99,46% of reserved) Uncommitted memory 8,61 MBytes (0,54% of reserved) Number of heap segments 39 segments Number of uncommitted ranges 41 range(s) Size of largest uncommitted range 8,33 MBytes Calculated heap fragmentation 3,27% Segment Information ------------------- Base Address | Reserved Size | Committed Size | Uncommitted Size | Number of uncommitted ranges | Largest uncommitted block | Calculated heap fragmentation 0x01040640 64,00 KBytes 64,00 KBytes 0 Bytes 0 0 Bytes 0,00% 0x01350000 1.024,00 KBytes 1.024,00 KBytes 0 Bytes 0 0 Bytes 0,00% 0x02850000 2,00 MBytes 2,00 MBytes 0 Bytes 0 0 Bytes 0,00% ...

¿Qué es esta información del segmento de todos modos?

Mirando las asignaciones que se enumeran:

Top 5 allocations by size ------------------------- Allocation Size - 336 1,18 GBytes Allocation Size - 1120004 121,77 MBytes ... Top 5 allocations by count -------------------------- Allocation Size - 336 3760923 allocation(s) Allocation Size - 32 1223794 allocation(s) ...

Podemos ver que aparentemente el montón MSVCR80 tiene 3.760.923 asignaciones en 336 bytes. Esto deja bastante claro que limpiamos nuestra memoria con muchas asignaciones pequeñas, pero ¿cómo podemos obtener más información sobre de dónde provino esta asignación ?

Si de alguna manera pudiéramos muestrear algunas de estas direcciones de asignación y luego verificamos en qué parte de la imagen de proceso se están utilizando estas direcciones, entonces, suponiendo que una gran parte de estas asignaciones sean responsables de nuestra "filtración", podríamos descubrir dónde estas asignaciones fuera de control vinieron de

Desafortunadamente, no tengo ni idea de cómo obtener más información del volcado en este momento.

¿Cómo podría inspeccionar este montón para ver algunas de las "336" direcciones de asignación?

¿Cómo puedo buscar estas direcciones en el volcado y luego averiguar qué variable de puntero (si existe) en la retención de volcado en estas direcciones?

¡Cualquier consejo relacionado con el uso de DebugDiag, WinDbg o cualquier otra herramienta realmente podría ayudar! Además, si no está de acuerdo con alguno de mis análisis anteriores, ¡avísenos! ¡Gracias!


En windbg, puede intentar usar !heap -l que debería rastrear los montones (tarda un tiempo, puede haber una manera de restringir la búsqueda a un montón específico para acelerarlo) y encontrar todos los bloques ocupados que no están referenciados en ninguna parte . Desde allí, abra la ventana de memoria ( alt + 5 ) y eche un vistazo a algunas de las entradas que coinciden con el tamaño de su asignación que sospecha que es su fuga. Con algo de suerte, podría haber algunos patrones comunes que pueden ayudarlo a identificar cuáles son los datos o, mejor aún, algunas cadenas ASCII que puede colocar de inmediato.

Desafortunadamente, no conozco ninguna otra buena manera, excepto intentar reproducirla al activar los seguimientos de pila de modo de usuario con gflags y usar umdh para tomar instantáneas de memoria.


Tú podrías:

  • investigue estos bloques de 336 bytes para ver si el contenido le dice algo sobre lo que les asignó. Para hacer eso, normalmente uso windbg. Primero ejecute el comando !heap -stat -h 0x01040000 que le dará el tamaño del bloque, luego pase este tamaño a !heap -flt s size que !heap -flt s todos los bloques de ese tamaño. Luego puede mirar en el bloque con cualquier comando que muestre memoria (como dc).
  • no puede reproducir el problema, pero puede ver en otro volcado qué asigna bloques de ese tamaño. Primero active la función de retroceso de pila utilizando la utilidad gflags -i your.exe +ust ( gflags -i your.exe +ust ). Luego ejecute su aplicación, obtenga un volcado y use el !heap -flt s para enumerar los bloques. Luego, el comando !heap -p -a blockaddress volcará la pila de funciones que asignaron el bloque.