2012-08-07 8 views
5

Estoy usando valgrind para intentar localizar una fuga de memoria es el cliente mysql C++ distribuido desde mysql.Usando valgrind para encontrar una pérdida de memoria en el cliente mysql C++

Tanto en los ejemplos (resultset.cpp) como en mi propio programa, hay un solo bloque de 56 bytes que no se libera. En mi propio programa, he rastreado la fuga a una llamada al cliente de mysql.

Estos son los resultados cuando corro la prueba:

valgrind --leak-check=full --show-reachable=yes ./my-executable 

==29858== Memcheck, a memory error detector 
==29858== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==29858== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
==29858== Command: ./my-executable 
==29858== 
==29858== 
==29858== HEAP SUMMARY: 
==29858==  in use at exit: 56 bytes in 1 blocks 
==29858== total heap usage: 693 allocs, 692 frees, 308,667 bytes allocated 
==29858== 
==29858== 56 bytes in 1 blocks are still reachable in loss record 1 of 1 
==29858== at 0x4C284A8: malloc (vg_replace_malloc.c:236) 
==29858== by 0x400D334: _dl_map_object_deps (dl-deps.c:506) 
==29858== by 0x4013652: dl_open_worker (dl-open.c:291) 
==29858== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==29858== by 0x4012FF9: _dl_open (dl-open.c:583) 
==29858== by 0x7077BCF: do_dlopen (dl-libc.c:86) 
==29858== by 0x400E9C5: _dl_catch_error (dl-error.c:178) 
==29858== by 0x7077D26: __libc_dlopen_mode (dl-libc.c:47) 
==29858== by 0x72E5FEB: pthread_cancel_init (unwind-forcedunwind.c:53) 
==29858== by 0x72E614B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126) 
==29858== by 0x72E408F: __pthread_unwind (unwind.c:130) 
==29858== by 0x72DDEB4: pthread_exit (pthreadP.h:265) 
==29858== 
==29858== LEAK SUMMARY: 
==29858== definitely lost: 0 bytes in 0 blocks 
==29858== indirectly lost: 0 bytes in 0 blocks 
==29858==  possibly lost: 0 bytes in 0 blocks 
==29858== still reachable: 56 bytes in 1 blocks 
==29858==   suppressed: 0 bytes in 0 blocks 
==29858== 
==29858== For counts of detected and suppressed errors, rerun with: -v 
==29858== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 6) 

Tengo algunas preguntas con respecto a este:

  1. ¿Cómo debería interpretar el bloque --show alcanzable?
  2. ¿Ese bloque es útil para que intente concentrarme en el error?
  3. Si el bloque no es útil, ¿tiene valgrind otro mecanismo que me ayude a rastrear la fuga?
  4. Si no, ¿hay alguna otra herramienta (con suerte OSS en Linux) que me ayude a reducir esto?

Gracias de antemano ..

ACTUALIZACIÓN: Este es el código que he encontrado en mi sistema para la definición de pthread_exit. No estoy seguro de que esta sea la fuente real que se invoca. Sin embargo, si es así, ¿alguien puede explicar lo que podría estar yendo mal?

void 
pthread_exit (void *retval) 
{ 
    /* specific to PTHREAD_TO_WINTHREAD */ 

    ExitThread ((DWORD) ((size_t) retval)); /* thread becomes signalled so its death can be waited upon */ 
    /*NOTREACHED*/ 
    assert (0); return; /* void fnc; can't return an error code */ 
} 

Respuesta

6

alcanzable sólo significa que los bloques tenían un puntero válido referencia a ellos en su alcance cuando el programa sale, lo que indica que el programa no lo hace de forma explícita en la salida libre de todo porque se basa en el sistema operativo subyacente para hacerlo. Lo que debe buscar es bloques perdidos, donde los bloques de memoria perdieron todas las referencias a ellos y ya no pueden liberarse.

Por lo tanto, los 56 bytes probablemente se asignaron en main, que no los liberaron explícitamente. Lo que publicaste no muestra una pérdida de memoria. Muestra la liberación principal de todo pero qué principal asignado porque main asume que cuando muera, toda la memoria será recuperada por el kernel.

Específicamente, es pthread (en general) haciendo esta suposición (que es una suposición válida en maldito cerca de todo lo que se encuentra en la producción escrita en los últimos 15 años o más). La necesidad de liberar bloques que todavía tienen una referencia válida al salir es un punto polémico, pero para esta pregunta específica, todo lo que se debe mencionar es que se hizo la suposición.

Editar

De hecho, es pthread_exit() no limpiar algo en la salida, pero como se explica probablemente no necesitará (o, posiblemente, no puede ) una vez que se llegue a ese punto.

+0

Gracias Tim. Eso definitivamente ayuda. ¿Tiene alguna sugerencia sobre cómo podría localizar la línea de código que no liberaba explícitamente la memoria? ¿Conoces alguna herramienta que pueda ser útil para hacer eso? – Homer6

+1

@ Homer6 En realidad se trata de hacerlo, nada que puedas arreglar (a menos que quieras profundizar en 'pthread_exit()', buscarlo, encontrarlo, liberarlo explícitamente) ... pero eso solo lo arregla en tu máquina :) –

+0

Gracias Tim.He publicado la definición (o lo que creo que es la definición) para pthread_exit. ¿Alguna idea sobre lo que podría estar pasando? – Homer6

Cuestiones relacionadas