【问题标题】:OpenSSL::SSL_library_init() memory leakOpenSSL::SSL_library_init() 内存泄漏
【发布时间】:2012-07-30 09:03:25
【问题描述】:

最近我开始研究 C++ 中的内存泄漏,所以我可能会问一个幼稚的问题。
我有一个使用 OpenSSL 的 c++ 库——我的任务是检查这个库中是否存在内存泄漏。我已运行 Visual Leak Detector 来检查内存泄漏。
我看到对SSL_library_init();SSL_load_error_strings(); 的调用导致泄漏 - 快速谷歌搜索显示在使用结束时我必须调用以下内容:

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

泄漏确实减少了,但仍然有两个泄漏(VLD 工具向我显示)是因为SSL_library_init 调用而发生的。
有谁知道我还需要做什么才能释放所有内存泄漏?

【问题讨论】:

  • 我不推荐 EVP_cleanup() 和 CRYPTO_cleanup_all_ex_data()。如果应用程序中使用了多个库,比如说 libssh2,我们不知道什么时候会调用它,这将卸载所有表并清理所有全局数据。考虑到这个问题,其中一个开源库 open Pegasus 实现了这一点,这导致我们的应用程序崩溃。这个开放的 pegasus 库在使用完成后会清除 openssl 的所有表和全局数据。由于清理,其他线​​程中的其他库在中间失败了。
  • 在正确的地方使用它很重要

标签: c++ windows memory-leaks openssl


【解决方案1】:

据我了解,在 SSL_library_init()SSL_load_error_strings() 期间分配的所有内存都存储在全局变量中,因此它属于“使用中的内存”类别,而不是内存泄漏类别,因为内存仍在程序快要结束时可以访问。

一个建议是必须在使用 SSL 的每个线程中调用 ERR_remove_state(0),因为当您使用参数 0 调用 ERR_remove_state 时,它只会清除当前线程的错误状态。其他电话对我来说似乎很好。如果您可以发布 VLD 仍在显示的“两个泄漏”,我可以检查一下。

【讨论】:

  • 首先,谢谢!,另外 - 如果我发布两个泄漏,你想看什么?泄漏来自 SSL_library_init() - 因为当我注释掉这个调用时 - VLD 不会报告任何泄漏。我还有两个问题: 1. 你能否请我参考任何网站,我可以了解更多关于内存泄漏与“使用中的内存”的信息? 2. 不知何故,VLD 有时不会向我显示由于 OpenSSL 功能而发生的泄漏的调用堆栈 - 你知道为什么吗?我使用 OpenSSl 作为编译到我的库中的静态库。
  • 如果您发布调用堆栈,我可以帮助检查 OpenSSL 中是否还有其他免费 API 可以调用。 1:对不起。我不知道任何网站。但是,关键是,在您退出应用程序之前,如果您需要内存,那么这是一种内存在使用中的情况。另一种情况是,您不需要内存,但是,您仍然有可以访问内存的指针,因此内存不会丢失,您仍然可以释放它。对于 2:OpenSSL 可能没有在 Debug 模式下编译,因为 VLD 无法提取足够的可以显示的信息。
  • 附加说明:我从 IBM Rational Purify 工具中获得了“正在使用的内存”的术语,我通常使用它来测试 Windows 中的内存泄漏。
  • 我不知道我是否可以从这个库发布调用堆栈 - 这个库是机密的。关于 Purify 的问题 - Purify 比 VLD 更好吗?或者它只是更复杂(更昂贵)?我可以获得 Purify 的试用版吗?
  • 我认为您应该能够获得 Purify 的试用版。它对 Windows 来说非常好,但也相当昂贵。您可以从 IBM Rational 网站获得所有详细信息。我自己没有使用过 VLD,所以无法评论哪个更好。
【解决方案2】:

为了摆脱分配的最后两个内存块 SSL_library_init() 试试:

sk_free(SSL_COMP_get_compression_methods());

【讨论】:

    【解决方案3】:

    摆脱 Joe H 回答中的编译错误:

    sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
    

    【讨论】:

    • 在循环中进行openssl初始化和反初始化时会导致内存错误
    【解决方案4】:

    致电SSL_COMP_free_compression_methods();

    【讨论】:

    • 你确定这个命令存在吗?它真的应该做一些与 4LegsDrivenCat 的回答不同的事情吗?
    • @Alex,当然存在,github.com/openssl/openssl/blob/master/ssl/ssl_ciph.c#L1909,这是释放压缩方法​​列表的正确方法(只要“正确”一词可以应用于 OpenSSL)。手动释放指针显然会在某处留下悬空指针。
    • 好吧,你是对的。我需要包含哪个标头才能访问此功能?我包含了您向我展示的文件中列出的所有标题,并且 ssl_locl.h 不存在(其他人没有)。我从 Shining Light Productions 安装了最新版本的 OpenSSL,即1.0.2a
    • 好的,你的函数很新,因为它在 1.0.1L 中没有,但 1.0.2a 有它。我进行了实验,发现如果我同时调用您的和提到的 4Legs,OpenSSL 不喜欢它,但如果我只调用其中一个,它们似乎可以达到相同的目的。万一有人在我之后想知道:我必须包括 ssl.h。
    猜你喜欢
    • 2013-11-29
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2013-01-20
    • 2011-10-31
    • 2019-08-10
    相关资源
    最近更新 更多