2012-08-01 18 views
14

Recentemente ho iniziato a studiare le perdite di memoria in C++, quindi potrei fare una domanda ingenua.
Ho una libreria C++ che sta usando OpenSSL - il mio compito è controllare se ci sono perdite di memoria in questa libreria. Ho lanciato Visual Leak Detector per controllare le perdite di mem.
vedo che le chiamate a SSL_library_init(); e SSL_load_error_strings(); conducono perdita - pratica googling dimostra che alla fine dell'utilizzo devo chiamare i seguenti:OpenSSL :: SSL_library_init() perdita di memoria

CONF_modules_free(); 
ERR_remove_state(0); 
ENGINE_cleanup(); 
CONF_modules_unload(1); 
ERR_free_strings(); 
EVP_cleanup(); 
CRYPTO_cleanup_all_ex_data(); 

La perdita infatti è diminuita, ma ancora ci sono due perdite (che lo strumento VLD mi mostra) che accade perché la chiamata SSL_library_init.
qualcuno sa cos'altro devo fare per liberare tutte le perdite di mem?

+0

Non consiglierei EVP_cleanup() e CRYPTO_cleanup_all_ex_data(). Se nell'applicazione sono presenti più librerie, diciamo libssh2, non sappiamo quando verrà chiamato, e questo scaricherà tutte le tabelle e pulirà tutti i dati globali. Prendendo in considerazione questa domanda, una delle librerie open source aperte da Pegasus lo ha implementato, e questo sta causando arresti anomali nella nostra applicazione. Questa libreria aperta di Pegasus sta cancellando tutta la tabella e i dati globali di openssl una volta che l'utilizzo è terminato. Altre librerie in altri thread stanno fallendo proprio nel mezzo a causa della pulizia. – Srikan

+0

L'utilizzo al posto giusto è importante. – Srikan

+1

Correlato, vedere anche [Come disinstallare correttamente OpenSSL] (http://stackoverflow.com/q/29845527). – jww

risposta

5

Come ho capito tutta la memoria allocata durante SSL_library_init() e SSL_load_error_strings() sono memorizzate in variabili globali e quindi rientra nella categoria di "Memoria in uso" piuttosto sotto la categoria di Perdita di memoria in quanto la memoria è ancora accessibile quando il il programma sta scomparendo

Un suggerimento è che ERR_remove_state(0) deve essere chiamato in ogni thread in cui viene utilizzato SSL, perché quando si chiama il ERR_remove_state con argomento 0, si cancella solo lo stato di errore per il thread corrente. Altre chiamate mi sembrano buone. Se puoi pubblicare "due perdite" che sono ancora visualizzate da VLD, posso controllare.

+1

In primo luogo, grazie !, in aggiunta - se inserisco le due fughe, cosa vuoi vedere? la perdita proviene da SSL_library_init() - perché quando commento questa chiamata - VLD non riporta alcuna perdita. Ho altre due domande: 1. puoi per favore indirizzarmi a qualsiasi sito web che possa imparare di più sulle perdite di memoria rispetto a "memoria in uso"? 2. in qualche modo il VLD a volte non mi mostra lo stack di chiamate per perdite che si verificano grazie alla funzione OpenSSL - sai perché? Sto usando OpenSSl come lib statico che è compilato nella mia libreria. – RRR

+1

Se pubblichi il callstack, posso aiutarti a verificare se c'è qualche altra API libera in OpenSSL da chiamare. Per 1: mi dispiace. Non sono a conoscenza di siti Web. Ma il punto è che, fino all'uscita dal punto di applicazione, se hai bisogno di una memoria, allora è un caso di memoria in uso. L'altro caso è che, non hai bisogno della memoria, ma hai ancora dei puntatori con cui puoi accedere alla memoria, quindi la memoria non è persa e puoi ancora liberarla. Per 2: OpenSSL potrebbe non essere stato compilato in modalità Debug a causa del quale VLD non è in grado di estrarre informazioni sufficienti che possono essere visualizzate. – Jay

+0

Nota aggiuntiva: Ho ottenuto la terminologia di "Memory In Use" dallo strumento IBM Rational Purify che generalmente utilizzo per verificare le perdite di memoria in Windows. – Jay

6

per sbarazzarsi degli ultimi due blocchi di memoria allocati in SSL_library_init() prova:

sk_free(SSL_COMP_get_compression_methods()); 
6

per sbarazzarsi di errore di compilazione nella risposta di Joe H:

sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); 
+0

che causerà un errore di memoria quando l'inizializzazione di openssl e la deinitializzazione vengono eseguite in un loop –

+0

Questo dovrebbe essere un commento. –

2

chiamata SSL_COMP_free_compression_methods();.

+0

Sei sicuro che questo comando esiste? E dovrebbe davvero fare qualcosa di diverso dalla risposta di 4LegsDrivenCat? – Alex

+1

@Alex, ovviamente esiste, https://github.com/openssl/openssl/blob/master/ssl/ssl_ciph.c#L1909 ed è il modo corretto (per quanto riguarda la parola "corretto" può essere applicato a OpenSSL) per liberare l'elenco dei metodi di compressione. Liberare manualmente il puntatore lascerà chiaramente un puntatore pendente da qualche parte. – avakar

+0

Ok, hai ragione. Quale intestazione devo includere per ottenere l'accesso a questa funzione? Ho incluso tutte le intestazioni elencate nel file che mi hai mostrato e ssl_locl.h non c'era (e gli altri non ce l'hanno). Ho installato la versione più recente di OpenSSL da Shining Light Productions, ovvero [1.0.2a] (http://slproweb.com/products/Win32OpenSSL.html) – Alex