2010-08-25 8 views
8

Quiero detectar fugas de memoria de mi programa C++ en Windows. He leído la documentación también en MSDN sobre mermoy leak detection y también comencé a usar Visual Leak Detector.detección de fuga de memoria en C++ con/sin Visual Leak Detector

Tengo una duda sobre el informe de las fugas. Estoy esperando un nombre de archivo con un número de línea, pero siempre me informan el texto a continuación. Tiene todos los componentes de una descripción de fuga (tipo de bloque, dirección de memoria, datos, etc.) excepto el nombre del archivo y el número de línea.

Si se trata de una fuga real? En caso afirmativo, ¿sabe por qué no se informa el archivo o la línea? Mientras tanto estoy teniendo una mirada también en this url

Gracias

 
Detected memory leaks! 
Dumping objects -> 
{4723} normal block at 0x04AFB5B8, 8 bytes long. 
Data: 2C 3F 00 00 28 3F 00 00 
{1476} normal block at 0x04AC3B58, 12 bytes long. 
Data: 00 CD CD CD EB 01 75 4C CA 3D 0B 00 
Object dump complete. 
+0

http://www.flipcode.com/archives/How_To_Find_Memory_Leaks.shtml – DumbCoder

+0

Esto es fuera de tema pero se informó antes de usar punteros inteligentes para evitar fugas manual de gestión de la memoria y de la memoria – Ahmed

+0

Debe utilizar Deleaker. debe ayudarte –

Respuesta

0

Debe utilizar Valgrind, es muy potente y explica adecuadamente dónde están las fugas localizadas en su programa. Sin embargo, es posible que su programa tenga que compilarse con gcc ...

+0

¡Conozco esta herramienta, pero me temo que debo seguir VC++! :) – user311906

+0

nada que le impida la construcción de ésta en gcc sin embargo, las fugas son los mismos lo que el compilador – Patrick

+3

asumir sus aplicaciones + bibliotecas que utiliza son compatibles tanto con Linux/gcc y ventanas/VC++ –

5

Este es el resultado del depurador CRT propio de Visual Studio, no el resultado de Visual Leak Detector. En primer lugar, asegúrese de estar utilizando la versión actual al Codeplex y de que ha #incluido vld.h en su proyecto. Obtendrás un resultado mucho más informativo.

+0

Hola mandril! Lamentablemente es la salida de Visual Leak Detector. Estoy usando una versión anterior tomada del sitio web de CodeProject no la de CODEPLEX ... así que supongo que debo actualizar + Comprobaré la configuración. IMPORTANTE: ¿puede confirmar suavemente que lo que escribí es una fuga real? – user311906

+0

Esa no es la salida de Visual Leak Detector: obtendrá muchos resultados con los sitios de llamadas donde se asignaron los objetos. Está viendo el resultado del detector de fugas de Visual Studio: http://msdn.microsoft.com/en-us/library/e5ewb1h3%28VS.80%29.aspx –

0

Rational Purify está disponible como un complemento económico para VC++, y es un detector de fugas (y otro problema) muy bueno. Solía ​​usarlo mucho en Solaris, y era muy fácil de usar y claro. También escuché cosas buenas de otras personas sobre la versión para usar con Visual Studio, pero nunca lo he intentado.

FWIW, sospecho que Purify fue la inspiración para Valgrind, que ya se ha mencionado.

0

Si los números de asignación (los que están en las llaves encrespadas) son siempre los mismos, this could help. Básicamente, describió cómo hacer que VC++ genere un punto de interrupción cuando se intenta la asignación con el número especificado.

+0

Hola SpaceComboy, ¡Gracias! Me di cuenta que; Veo que en algún proyecto se mantiene igual y en otros cambios. – user311906

+0

@ user311906: los números de asignación solo cuentan todas las asignaciones de pila realizadas. Si su aplicación realiza las asignaciones en el mismo orden cada vez, las cifras de las asignaciones filtradas no cambiarán, y puede usarlas para rastrear el origen del problema. Esto es incluso más útil que solo el archivo y número de línea, porque también le dará el estado actual de la aplicación. –

7

Investigué algunas formas diferentes de rastrear las pérdidas de memoria. Todos ellos tienen sus ventajas, pero también sus desventajas.

para entender sus ventajas y desventajas, tenemos que entender los diferentes mecanismos y requisitos:

  1. Cómo son nuevos, borrar, malloc e interceptado libre? Algunas herramientas usan #define para redefinir new, delete, malloc y free, pero esto depende del orden correcto de los archivos include, y puede dar problemas si una clase contiene, por ejemplo, un método llamado libre (como es el caso en Qt). El preprocesador también redefinirá este método, lo que puede generar errores de compilación o elementos externos no resueltos.

    Otra forma es anular los operadores globales nuevos y eliminar. Esta es una solución mucho más limpia, pero falla tener una biblioteca de terceros que pone una nueva en la biblioteca, pero la elimina en el encabezado (o viceversa).

  2. Cómo se determina la fuente de la llamada. Si es nuevo, eliminar, ...se interceptan utilizando # define, a menudo los símbolos del preprocesador __FILE__ y __LINE__ se usan para obtener la fuente de la fuga. Sin embargo, si tiene funciones "genéricas" en su código, como p. Ej. CreateString(), la mayoría de las filtraciones se informarán en estas funciones genéricas, lo que realmente no te ayuda.

    Una alternativa es obtener la pila de llamadas en tiempo de ejecución. Se puede hacer fácilmente usando la función Windows StackWalk, pero en mi experiencia, esto es muy, muy lento. Una alternativa mucho más rápida es obtener el puntero base directamente y confiar en los punteros de marco de pila (debe compilar con/Oy para obtener los punteros de marco de pila). Puede obtener el puntero de marco (base) como este: _asm mov DWORD PTR [FramePtr], ebp. Después, simplemente bucle y en el bucle de obtener el puntero de instrucción de ((ADDR *)FramePtr)[1]; y el siguiente cuadro triple desde FramePtr = ((ADDR *)FramePtr)[0];

  3. Cómo informar de las fugas en el momento exacto. En mi caso, quiero que se informen las fugas al final de la aplicación, pero para poder hacer esto, se necesita un mecanismo de informe de fugas al final de la aplicación. Esto significa que si quiere reportar sus filtraciones usted mismo, necesita confiar en las variables globales que están siendo destruidas al final de su aplicación (e informar las fugas en el destructor de la variable global). Para las aplicaciones tipo servidor, probablemente esté más interesado en obtener la diferencia en el uso de la memoria entre dos puntos en el tiempo.

Y ahora los diferentes sistemas: fugas

  1. C Duración: informes de fugas en el final, pero no tiene manera decente de informar pilas de llamadas. Su método de interceptar llamadas a nuevo, eliminar, ... puede causar problemas en combinaciones con bibliotecas de terceros (como Qt, Boost, ...)

  2. Utilidades externas de Microsoft (como GFlags, UMDH ,, ...): parece que solo pueden registrar diferencias entre dos puntos en el tiempo. Sin embargo, la pila de llamadas parece ser mucho mejor, aunque la utilidad GFlags puede establecer indicadores en el sistema operativo que pueden causar una grave desaceleración de la aplicación.

  3. Visual Leak Detector. Parece que encuentra todas las fugas correctamente, pero en mi caso no funciona, ya que tengo una DLL de terceros que simplemente aborta el proceso en su DllUnload (parece ser un problema específico de Windows 7).

  4. Mi favorito personal (y la gente no estará de acuerdo conmigo, estoy seguro), es escribir su propio administrador de memoria. La interceptación se puede hacer fácilmente utilizando operadores globales nuevos y de eliminación (con los posibles problemas mencionados anteriormente), y puede obtener la pila de llamadas como se describe anteriormente. Esta alternativa también se basa en poder tener código que se ejecuta en el último momento de su aplicación.

Al elegir una alternativa, me encontré con los siguientes aspectos muy imporantes para mi situación:

  • quiero que funcione fichero de tus ajustes en mi aplicación, de manera que todos los desarrolladores se notifica inmediatamente si hay una fuga. Si demora la verificación de fugas a un momento posterior en el que utiliza servicios externos como Purify, la búsqueda de fugas será mucho más difícil.
  • Quiero que se informen las fugas al final de la aplicación, automáticamente.
  • que desea tanto como sea posible, la información de la fuga (los datos, la pila de llamadas, ...)

Espero que esto ayude.

2

Ok. Lo obtuve después de depurar muchos archivos de encabezado.

Esto es lo que tiene que hacer para que el número de archivo/línea en la salida

"_CRTDBG_MAP_ALLOC#define"

"#define _CRTDBG_MAP_ALLOC_NEW"

+0

por alguna razón esos dos define simplemente me dicen: c: \ archivos de programa (x86) \ Microsoft Visual Studio 10.0 \ VC \ include \ crtdbg.h (1116): {} 640 bloque normal en 0x000A5E28, 12 bytes de longitud. además de la fuga ... doesnt realmente ayudan –

+0

ajustes de esto desencadena este aviso: c: \ Archivos de programa \ Microsoft Visual Studio 9.0 \ VC \ include \ crtdbg.h (1203): C4985 ​​advertencia: 'operador de nuevo' : atributos no presentes en la declaración anterior – Arthur

1

¿Usted compilar con la depuración habilitada información y asegúrese de que el archivo pdb esté disponible por el detector de fugas? Sin esta información, no podría proporcionar números de línea.

Cuestiones relacionadas