2009-10-09 16 views
11

Recentemente ho eseguito il debug di alcune app con valgrind e sto ottenendo rapporti molto strani da dlopen.Perdita di memoria riportata da valgrind in 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> 

Questo appare come il messaggio di errore che viene inizializzato per dlerror, ma guardando la pagina man, non dice nulla su come questo dovrebbe essere cancellato. Qualche idea su come sbarazzarsi di questo?

+0

stai usando 'dlclose()'? – LiraNuna

+0

sì, certo, ho ricontrollato che dlclose è correttamente chiamato - ma solo se dlopen restituisce qualcosa! = NULL, e sospetto che sia da casi in cui dlopen _does_ restituisce 0 – Anteru

risposta

8

Era in grado di riprodurre questo problema con un codice 'ciao mondo', che non chiama nemmeno simboli nell'oggetto caricato. http://pastebin.com/d690bea57

Presumo che sia un errore in libc o valgrind. Riproducibile su Ubuntu 9.04 e Scientific Linux 5.3 (rispettivamente 20 e 32 byte).

EDIT (da Calmarius):

Questo codice banale riproduce il problema:

#include <dlfcn.h> 

int main() 
{ 
    void* handle = 0; 

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

    return 0; 
} 

Quando viene compilato con questo comando:

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

Anche l'ultima valgrind 3.11 può riprodurre questo su Ubuntu 14.04

Bug a monte è stato segnalato: https://bugs.kde.org/show_bug.cgi?id=358980

+0

Un amico ha sottolineato che si tratta di un bug in Valgrind. https://issues.asterisk.org/view.php?id=16007 Vedere il file di soppressione valgrind allegato. –

+4

Ho scoperto che valgrind non segnalerà questa perdita se si termina il codice con pthread_exit (NULL), anche se non si utilizzano affatto pthreads. Forse questo può aiutare qualcuno. Potrebbe essere meno complicato rispetto alla scrittura di un file di soppressione di valgrind. –

+0

Suppongo che la chiamata a pthread_exit ripulisca la memoria locale del thread che viene utilizzata per memorizzare il testo dell'errore (in modo che sia multi-thread sicuro - è sufficiente l'affinità del thread tra le chiamate a dlopen e dlerror). – KayEss

1

L'ho visto io stesso in tutti i tipi di librerie, usando dlopen o no. Ho appena dato per scontato che si trattasse di un'implementazione magica all'interno delle librerie che ha ingannato valgrind - o - queste librerie hanno effettivamente perdite di memoria, nel qual caso non c'è nulla che io possa fare all'interno dell'app my.

2

Questa soppressione è meglio:

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

(. Si noti che il "..." fa parte della soppressione e dovrebbe essere entrato letteralmente)