在使用OpenSSL的RSA加解密的時候,發現RSA_new()初始化和RSA_free()釋放RSA結構體后依然會有內存泄漏。網上Baidu、Google之,發現這個相關信息很少(至少中文搜索結果是這樣,不知是研究這個的人太少還是這個太基礎了。。。),最后終于在某個E文論壇上找到了解決辦法。在這里總結了一下,供大家參考。我的OpenSSL版本是0.9.8l。
具體如下:
RSA * rsa = RSA_new();
RSA_free( rsa );
產生內存泄漏:
Debug for memory leaks
Dumping?objects?- >
{ 140 }?normal?block?at? 0x003B97A0 , ? 12 ?bytes?long .
?Data:? < ?? ; ????????? > ?B8? 96 ?3B? 00 ? 00 ? 00 ? 00 ? 00 ? 06 ? 00 ? 00 ? 00 ?
{ 139 }?normal?block?at? 0x003B9750 , ? 16 ?bytes?long .
?Data:? < ???????????????? > ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ?
{ 138 }?normal?block?at? 0x003B9700 , ? 20 ?bytes?long .
?Data:? < ????P? ; ????????? > ? 00 ? 00 ? 00 ? 00 ? 50 ? 97 ?3B? 00 ? 00 ? 00 ? 00 ? 00 ? 04 ? 00 ? 00 ? 00 ?
{ 137 }?normal?block?at? 0x003B96B8 , ? 12 ?bytes?long .
?Data:? < ?????? ; ????? > ? 06 ? 00 ? 00 ? 00 ? 00 ? 97 ?3B? 00 ? 00 ? 00 ? 00 ? 00 ?
{ 136 }?normal?block?at? 0x003B9638 , ? 64 ?bytes?long .
?Data:? < ???????????????? > ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ? 00 ?
{ 135 }?normal?block?at? 0x003B9598 , ? 96 ?bytes?long .
?Data:? < 8 ? ; ???A???A????? > ? 38 ? 96 ?3B? 00 ?C0?FD? 41 ? 00 ?B0?FD? 41 ? 00 ? 08 ? 00 ? 00 ? 00 ?
Object?dump?complete .
?
解決方法很簡單:
調用OpenSSL的crypto庫,在退出前需要調用API "CRYPTO_cleanup_all_ex_data",清除管理CRYPTO_EX_DATA的全局hash表中的數據,避免內存泄漏。如下:
RSA * rsa = RSA_new();
RSA_free( rsa );
CRYPTO_cleanup_all_ex_data();?
這樣就沒有內存泄漏了。
?
需要注意的是,CRYPTO_cleanup_all_ex_data()不能在potential race-conditions條件在調用(不太懂這個術語,我理解的意思是當函數外部存在RSA結構體的時候,在函數內部執行CRYPTO_cleanup_all_ex_data()將導致函數外的RSA結構體也被清理掉),因此最好在程序結束的時候才調用。
關于CRYPTO_cleanup_all_ex_data()的注釋說明和代碼如下:
?*?thread-safe?without?overhauling?a?lot?of?stuff,?and?shouldn't?really?be
?*?called?under?potential?race-conditions?anyway?(it's?for?program?shutdown
?*?after?all).? */
void ?CRYPTO_cleanup_all_ex_data( void )
????{
????IMPL_CHECK
????EX_IMPL(cleanup)();
????}
同樣,其他相應的模塊也需要在使用后清理:
EVP_cleanup();????????????????? // For?EVP
ENGINE_cleanup();?????????????? // for?engine
CRYPTO_cleanup_all_ex_data();?? // generic?
ERR_remove_state( 0 );??????????? // for?ERR
ERR_free_strings();???????????? // for?ERR
??http://www.cnblogs.com/moonset7/archive/2009/12/30/1635770.html
?


