recoleccion programacion memoria liberar leaks basura avoid c++ winapi memory-leaks

c++ - memoria - recoleccion de basura en programacion



Detección de fuga de memoria mientras se ejecutan pruebas unitarias (5)

Para obtener este tipo de información, anulamos new / delete y malloc / free, proporcionando nuestras propias implementaciones de montón que almacenan stacktraces en la asignación y producen un informe cuando se destruye el montón (además de agregar centinelas para detectar sobrepasamientos de búfer).

Esto es un poco de trabajo la primera vez que lo haces. Este tipo ha escrito una herramienta freeware que maneja todos los bits duros, no lo he probado yo mismo, pero su explicación de cómo lo escribió es útil cuando lo haces tú mismo.

Tengo una aplicación Win32 C ++ con un conjunto de pruebas unitarias. Después de que las pruebas de la unidad hayan terminado de ejecutarse, me gustaría que se genere automáticamente un informe legible por el ser humano sobre cualquier memoria no liberada. Idealmente, el informe tendrá una pila con archivos e información de número de línea para cada asignación no liberada. Sería bueno tenerlos generados en un orden consistente para facilitar la diferenciación de una ejecución a la siguiente. (Básicamente, me gustaría obtener los resultados de valgrind --leak-check = full, pero en windows).

Tuve éxito con UMDH al obtener este tipo de información de los procesos en ejecución, pero esa herramienta solo parece funcionar si se conecta a un proceso existente. Quiero que esto suceda automáticamente cada vez que ejecuto mis pruebas unitarias.

¿Hay alguna herramienta que pueda hacer esto? Si es así, ¿cómo lo uso?

¡Gracias!


Puede definir DEBUG_NEW y eso enciende alguna detección de fugas, debe definirla antes de incluir cualquier sistema que incluya archivos. Solo verifica las fugas utilizando el nuevo operador y, por supuesto, debe recompilar el código para que no pueda adjuntarlo como valgrind.

Ver más información aquí:

http://msdn.microsoft.com/en-us/library/tz7sxz99(VS.80).aspx


Si está utilizando MSVC, las funciones del montón de depuración de Microsoft se pueden usar para generar el informe que desea, pero puede no ser tan automático como desee (puede que necesite escribir algún código personalizado):

_CrtSetReportMode _CrtSetReportFile _CrtMemState _CrtMemCheckpoint _CrtMemDumpStatistics _CrtSetReportFile _CrtSetDbgFlag


Jugué con las funciones de CRT Debug Heap, señaló Mike B, pero al final no estaba satisfecho con solo obtener la dirección de la memoria filtrada. Obtener los stacks como UMDH proporciona hace que la depuración sea mucho más rápida. Entonces, en mi función main () ahora lanzo UMDH usando CreateProcess antes y después de ejecutar las pruebas para tomar instantáneas de montón. También escribí un archivo de lotes trivial que ejecuta mi arnés de prueba y luego difills las instantáneas de montón. Así que, lanzo el archivo por lotes y obtengo los resultados de mis pruebas y un archivo de texto con todas las acumulaciones de asignaciones sin actualizar, todo en una sola toma.

UMDH recoge una gran cantidad de falsos positivos, por lo que tal vez un híbrido de las cosas CrtDebug y lo que estoy haciendo ahora sería una mejor solución. Pero por ahora estoy contento con lo que tengo.

Ahora si tuviera una forma de detectar si no cerraba las manijas ...


Lo hice una vez, pero no fue tan automático. No tengo acceso a ese código ahora, pero esta es la idea:

Usé las funciones de depuración que Mike B ha mencionado (por cierto, solo funcionan en Debug).

El corredor de pruebas ejecutó todas las pruebas dos veces, porque durante la primera ejecución la memoria se asigna para globales. La segunda vez, se verificó el número total de bloques asignados antes y después de cada prueba (creo que puedes hacerlo en setUp () y tearDown ()). Si el número era diferente, significaba una pérdida de memoria y la prueba fallaba con un mensaje apropiado. Por supuesto, si la prueba falla, debe conservar su mensaje de error. Ahora para encontrar la fuga, tuve que leer el número de asignación de bloque de la última asignación usando pBlockHeader, luego establecer un punto de interrupción con _CrtSetBreakAlloc y ejecutar nuevamente.

Más sobre esto aquí: http://levsblog.wordpress.com/2008/10/31/unit-testing-memory-leaks/