2012-01-31 24 views
15

Si queremos comprobar si hay pérdidas de memoria en un programa C++, podemos sobrecargar los operadores new y delete para realizar un seguimiento de la memoria asignada. ¿Qué pasa si nos gustaría verificar si hay fugas en un programa C? Como no hay sobrecarga del operador en C, ¿podemos sobreescribir el puntero de función malloc para interceptar llamadas a malloc y asignar la asignación de memoria? ¿Hay una manera más fácil sin usar ningún servicio externo? Proporcione algún código ya que no estoy familiarizado con los punteros del método de sobreescritura.¿Detecta fugas de memoria en programas C?

Nota: Me gustaría hacer esto sin ninguna utilidad externa para la práctica.

+4

¿Qué pasa con Valgrind? –

+0

@MitchWheat mencioné que no puedo usar ningún servicio externo –

+0

Bueno, si esto es para aprender, podrías aprender sobre cómo lo hace valgrind ... –

Respuesta

35

Según lo sugerido, ya existen excelentes herramientas como Valgrind para hacer esto.

adicional:

me gustaría hacer esto sin ningún tipo de utilidades externas para la práctica
Esto es interesante y estoy seguro estaría cumpliendo,
Puede utilizar truco macro para detectar tales uso de memoria y errores de fuga, de hecho, escriba su propio detector de fugas ordenado. Debería poder hacer esto siempre que tenga una sola función de asignación y desasignación en su proyecto.

#define malloc(X) my_malloc(X, __FILE__, __LINE__, __FUNCTION__) 

void* my_malloc(size_t size, const char *file, int line, const char *func) 
{ 

    void *p = malloc(size); 
    printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size); 

    /*Link List functionality goes in here*/ 

    return p; 
} 

Mantiene una lista vinculada de direcciones asignadas con el archivo y el número de línea desde donde se asignó. Actualiza la lista de enlaces con entradas en su malloc.

Al igual que en el ejemplo anterior, puede escribir una implementación para free, en la que verifica las entradas de dirección que se piden para ser liberadas en su lista vinculada. Si no hay entradas coincidentes, se trata de un error de uso y puede marcarlo.

Al final de su programa imprime o escribe el contenido de su lista vinculada a un archivo de registro. Si no hay filtraciones, su lista vinculada no debería tener entradas, pero si hay algunas filtraciones, entonces el archivo de registro le brinda la ubicación exacta de donde se asignó la memoria.

Tenga en cuenta que al usar este macro truco, pierde el tipo de comprobación que ofrecen las funciones, pero es un pequeño truco que utilizo muchas veces.

Espero que esto ayude y todo lo mejor :)

+0

Este es un enfoque definitivo e interesante, ¿puedo agregar tamaño a algún contador cuando se invoca malloc y luego restar tamaño cuando se invoca a libre? –

+3

Podría, pero eso no le dará la granularidad que pueda desear. Entonces perdiste 2000 bytes. ¿Fue una asignación de 2000 bytes o 10 asignaciones de 200 bytes? Una lista te ahorraría mucho tiempo yendo a través de un registro tratando de hacer coincidir las cosas. – Duck

+0

@MikeG: Sí, como correctamente dijo Duck, la lista vinculada le brinda la flexibilidad y la funcionalidad para determinar con precisión las asignaciones de fallas. –

10

Valgrind es lo que necesita.

Recuerdo haber leído el primer capítulo de Algorithms in a Nutshell que hablaba de esto aunque no incluía el código. Acaba de agregarse en caso de que lo encuentre interesante.

ya que no hay sobrecarga de operadores en C podemos sobre-escritura malloc punto de función para interceptar llamadas a malloc y realizar un seguimiento de memoria asignación

En realidad, se puede. DIGA LD_PRELOAD una lectura.

+0

Sé cómo usar Valgrind solo quiero implementarlo –

+1

@MikeG: Esto es como si tuvieras cáncer y "sabes sobre hospitales, pero quiero intentar curarlo para practicar". –

+5

@KerrekSB: No hay nada malo en jugar con eso, sin duda es una gran experiencia de aprendizaje. Por supuesto, Valgrind es el mejor en un entorno de proyecto en tiempo real, pero debo admitir que fue un buen aprendizaje para mí cuando lo hice por mucho tiempo. hace tiempo. –

4

Además de la respuesta de @ Als que envuelva las llamadas en el código fuente, si está usando GNU ld, puede hacer que el enlazador envolver todas las llamadas (presumiblemente a malloc, realloc, calloc y free) en tiempo de enlace, independientemente de dónde provengan. A continuación, escriba __wrap_malloc etc. y puede llamar a la función original con, por ejemplo, __real_malloc.

Ver --wrap=symbol en http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html

No sé cómo funciona esto con llamadas de bibliotecas compartidas. Supongo que no.

1

Aquí es cómo se puede modificar malloc, ganchos libres: Hooks for Malloc

+1

los hipervínculos cambian. debes describir la solución que encontraste en el enlace –

1

Uso mallinfo funcionar funcionó para mí en Xilinx Zynq Baremetal usando Xilinx SDK gcc. Probé con una fuga de memoria intencional. No tengo idea de por qué, pero los resultados de Google fueron increíblemente terribles al encontrar esta solución. ¡Difundir la voz para ayudar a otros desarrolladores!