S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

在使用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

 


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理