Posted on 2010-01-15 11:42
S.l.e!ep.¢% 閱讀(797)
評論(0) 編輯 收藏 引用
在使用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
Detected?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()的注釋說明和代碼如下:
/*
?Release?all?"ex_data"?state?to?prevent?memory?leaks.?This?can't?be?made
?*?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)();
????}
?
同樣,其他相應的模塊也需要在使用后清理:
CONF_modules_unload(
1
);????????
//
for?conf
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
?