Todas las funciones mencionadas en este bloque son funciones de biblioteca. ¿Cómo puedo rectificar esta pérdida de memoria?
Se incluye en la categoría " Aún accesible ". (Hay 4 más, que son muy similares, pero de diferentes tamaños)
630 bytes in 1 blocks are still reachable in loss record 5 of 5
at 0x4004F1B: calloc (vg_replace_malloc.c:418)
by 0x931CD2: _dl_new_object (dl-object.c:52)
by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
by 0x92EFB6: _dl_map_object (dl-load.c:2251)
by 0x939F1B: dl_open_worker (dl-open.c:255)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0x9399C5: _dl_open (dl-open.c:584)
by 0xA64E31: do_dlopen (dl-libc.c:86)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
Captura: una vez que ejecuté mi programa, no dio pérdidas de memoria, pero tenía una línea adicional en la salida de Valgrind, que no estaba presente antes:
Descartando syms en 0x5296fa0-0x52af438 en /lib/libgcc_s-4.4.4-20100630.so.1 debido a munmap ()
Si la fuga no se puede rectificar, ¿puede alguien explicar al menos por qué la línea munmap () hace que Valgrind informe 0 fugas "aún accesibles"?
Editar:
Aquí hay una muestra de prueba mínima:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *runner(void *param) {
/* some operations ... */
pthread_exit(NULL);
}
int n;
int main(void) {
int i;
pthread_t *threadIdArray;
n=10; /* for example */
threadIdArray = malloc((n+n-1)*sizeof(pthread_t));
for(i=0;i<(n+n-1);i++) {
if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
printf("Couldn't create thread %d\n",i);
exit(1);
}
}
for(i=0;i<(n+n-1);i++) {
pthread_join(threadIdArray[i],NULL);
}
free(threadIdArray);
return(0);
}
Corre con:
valgrind -v --leak-check=full --show-reachable=yes ./a.out
Respuestas:
Hay más de una forma de definir "pérdida de memoria". En particular, hay dos definiciones principales de "pérdida de memoria" que son de uso común entre los programadores.
La primera definición comúnmente utilizada de "pérdida de memoria" es: "La memoria se asignó y no se liberó posteriormente antes de que el programa terminara". Sin embargo, muchos programadores (con razón) argumentan que ciertos tipos de pérdidas de memoria que se ajustan a esta definición en realidad no plantean ningún tipo de problema y, por lo tanto, no deben considerarse verdaderas "pérdidas de memoria".
Una definición posiblemente más estricta (y más útil) de "pérdida de memoria" es: "La memoria se asignó y no se puede liberar posteriormente porque el programa ya no tiene ningún puntero al bloque de memoria asignado". En otras palabras, no puede liberar memoria a la que ya no tiene punteros. Tal memoria es, por lo tanto, una "pérdida de memoria". Valgrind utiliza esta definición más estricta del término "pérdida de memoria". Este es el tipo de fuga que potencialmente puede causar un agotamiento significativo en el montón, especialmente para procesos de larga duración.
La categoría "todavía accesible" dentro del informe de pérdida de Valgrind se refiere a asignaciones que se ajustan solo a la primera definición de "pérdida de memoria". Estos bloques no se liberaron, pero podrían haberse liberado (si el programador hubiera querido hacerlo) porque el programa seguía haciendo un seguimiento de los punteros a esos bloques de memoria.
En general, no hay necesidad de preocuparse por los bloques "aún accesibles". No plantean el tipo de problema que pueden causar las verdaderas pérdidas de memoria. Por ejemplo, normalmente no hay potencial para el agotamiento del montón de bloques "aún accesibles". Esto se debe a que estos bloques suelen ser asignaciones de una sola vez, cuyas referencias se mantienen durante toda la vida útil del proceso. Si bien puede continuar y asegurarse de que su programa libere toda la memoria asignada, por lo general no hay ningún beneficio práctico al hacerlo, ya que el sistema operativo recuperará toda la memoria del proceso después de que el proceso finalice, de todos modos. Contrasta esto con verdad pérdidas de memoria que, si no se corrigen, podrían hacer que un proceso se quede sin memoria si se ejecuta el tiempo suficiente, o simplemente hará que un proceso consuma mucha más memoria de la necesaria.
Probablemente, el único momento en que es útil asegurarse de que todas las asignaciones tengan "liberaciones" coincidentes es si sus herramientas de detección de fugas no pueden determinar qué bloques son "aún accesibles" (pero Valgrind puede hacer esto) o si su sistema operativo no reclama todo la memoria de un proceso final (todas las plataformas que Valgrind ha sido portado para hacer esto).
fuente
munmap
se invoque como resultado de descargar un objeto compartido. Y todos los recursos utilizados por el objeto compartido podrían liberarse antes de que se descargue. Esto podría explicar por qué los "todavía alcanzables" se están liberando en elmunmap
caso. Sin embargo, solo estoy especulando aquí. No hay suficiente información aquí para decir con certeza.Dado que hay una rutina de la familia pthread en la parte inferior (pero no sé cuál en particular), supongo que ha lanzado un hilo como unible que ha terminado la ejecución.
La información del estado de salida de ese hilo se mantiene disponible hasta que llame
pthread_join
. Por lo tanto, la memoria se mantiene en un registro de pérdida al finalizar el programa, pero aún se puedepthread_join
acceder a ella, ya que podría usarla para acceder a ella.Si este análisis es correcto, inicie estos hilos separados o únase a ellos antes de finalizar su programa.
Editar : ejecuté su programa de muestra (después de algunas correcciones obvias) y no tengo errores, pero los siguientes
Dado que la
dl-
cosa se parece mucho a lo que ves, supongo que ves un problema conocido que tiene una solución en términos de un archivo de supresiónvalgrind
. Quizás su sistema no esté actualizado o su distribución no mantenga estas cosas. (El mío es ubuntu 10.4, 64 bits)fuente
No pareces entender lo que
still reachable
significa.Cualquier cosa no
still reachable
es una fuga. No necesitas hacer nada al respecto.fuente
FILE
punteros perdidos ?Aquí hay una explicación adecuada de "todavía accesible":
"Aún accesible" son fugas asignadas a variables globales y estáticas locales. Debido a que valgrind rastrea las variables globales y estáticas, puede excluir las asignaciones de memoria que se asignan "una vez y olvidar". Una variable global asignó una asignación una vez y nunca reasignó que la asignación no suele ser una "fuga" en el sentido de que no crece indefinidamente. Sigue siendo una fuga en sentido estricto, pero generalmente puede ignorarse a menos que sea pedante.
Las variables locales a las que se asignan asignaciones y no se liberan casi siempre son fugas.
Aquí hay un ejemplo
Valgrind informará working_buf como "todavía accesible - 16k" y temp_buf como "definitivamente perdido - 5k".
fuente
Para futuros lectores, "Aún accesible" podría significar que olvidó cerrar algo como un archivo. Si bien no parece ser así en la pregunta original, siempre debes asegurarte de haberlo hecho.
fuente