2009-10-09 16 views
11

He estado depurando alguna aplicación últimamente con valgrind, y recibo informes muy extraños desde dlopen.¿Fuga de memoria informada por valgrind en dlopen?

==1987== 32 bytes in 1 blocks are still reachable in loss record 1 of 2 
==1987== at 0x4C24477: calloc (vg_replace_malloc.c:418) 
==1987== by 0x570F31F: _dlerror_run (dlerror.c:142) 
==1987== by 0x570EEE0: [email protected]@GLIBC_2.2.5 (dlopen.c:88) 
     <my call to dlopen> 
==1987== 
==1987== 264 bytes in 1 blocks are still reachable in loss record 2 of 2 
==1987== at 0x4C25153: malloc (vg_replace_malloc.c:195) 
==1987== by 0x400CD44: _dl_map_object_deps (dl-deps.c:506) 
==1987== by 0x4012DA2: dl_open_worker (dl-open.c:326) 
==1987== by 0x400E385: _dl_catch_error (dl-error.c:178) 
==1987== by 0x40126C6: _dl_open (dl-open.c:615) 
==1987== by 0x570EF65: dlopen_doit (dlopen.c:67) 
==1987== by 0x400E385: _dl_catch_error (dl-error.c:178) 
==1987== by 0x570F2AB: _dlerror_run (dlerror.c:164) 
==1987== by 0x570EEE0: [email protected]@GLIBC_2.2.5 (dlopen.c:88) 
     <my call to dlopen> 

Esto parece el mensaje de error que se inicializa para dlerror, pero mirando a la página del manual, que no dice nada acerca de cómo debe ser limpiado. ¿Alguna idea de cómo deshacerse de esto correctamente?

+0

¿Está utilizando 'dlclose()'? – LiraNuna

+0

sí, por supuesto, comprobé que dlclose se llame correctamente, pero solo si dlopen devuelve algo! = NULL, y sospecho que esto es de casos donde dlopen _does_ return 0 – Anteru

Respuesta

8

Pude reproducir este problema con un código 'hola mundo', que ni siquiera llama a ningún símbolo en el objeto cargado. http://pastebin.com/d690bea57

Supongo que es un error en libc o valgrind. Reproducible en Ubuntu 9.04 y Scientific Linux 5.3 (20 y 32 bytes respectivamente).

EDITAR (por Calmarius):

Este código trivial reproduce el problema:

#include <dlfcn.h> 

int main() 
{ 
    void* handle = 0; 

    handle = dlopen("libm.so", RTLD_NOW); 
    dlclose(handle);  

    return 0; 
} 

cuando se compila con este comando:

gcc -Wl,--no-as-needed -g -o stuff main.c -ldl -lpthread 

Incluso la última valgrind 3.11 puede reproducir esto en Ubuntu 14.04

Error de Upstream ha sido reportado: https://bugs.kde.org/show_bug.cgi?id=358980

+0

Un amigo señaló que es un error en Valgrind. https://issues.asterisk.org/view.php?id=16007 Consulte el archivo de supresión valgrind adjunto. –

+4

Descubrí que valgrind no informará esta pérdida si finalizas tu código con pthread_exit (NULL), incluso si no estás utilizando pthreads en absoluto. Tal vez esto pueda ayudar a alguien. Puede ser menos engorroso que escribir un archivo de supresión de valgrind. –

+0

Supongo que la llamada a pthread_exit limpia el almacenamiento local de subprocesos que se usa para almacenar el texto de error (para que sea seguro para varios subprocesos; simplemente necesita afinidad de subprocesos entre las llamadas a dlopen y dlerror). – KayEss

1

He visto esto en todo tipo de libs, usando dlopen o no. Simplemente asumí que fue una implementación mágica dentro de las librerías que engañó a valgrind - o - estas libs realmente tienen pérdidas de memoria en cuyo caso no hay nada que pueda hacer dentro de mi aplicación.

2

Esta supresión es mejor:

{ 
    Ignore dlopen bug. 
    Memcheck:Leak 
    ... 
    fun:_dl_open 
    ... 
} 

(. Tenga en cuenta que el "..." es parte de la supresión y debe introducirse literalmente)