c++ openssl 1.1.1在线程中运行RSA算法导致内存泄漏

标签 c++ multithreading memory-leaks openssl rsa

这很奇怪!我环顾四周,什么也没找到。我的测试代码如下:

#include "pch.h"
#include "Windows.h"
#include "openssl/ssl.h"
 
#pragma comment(lib,"../Include/lib/libssl.lib")
#pragma comment(lib,"../Include/lib/libcrypto.lib")
#pragma comment(lib,"Crypt32.lib")
#pragma comment(lib,"ws2_32.lib")
 
#include <stdlib.h>
#include <crtdbg.h>
 
#define _CRTDBG_MAP_ALLOC
 
const char* priKey = "607BC8BA457EC0A1B5ABAD88061502BEA5844E17C7DD247345CD57E501B3300B4B8889D3DFCF5017847606508DF8B283C701F35007D5F4DBA96023DD3B0CCE062D8F63BCC16021B944A1E88861B70D456BAA1E0E69C90DFCA13B4D4EA5403DA25FEBF94B0515644A7D2DF88299189688DA5D8951512ADC3B1A35BAEEC147F69AB101048B9029E65A77A438A05AE30337E82B0571B80A955C72EA0DB3B457ECC8B81F346624E3D22755FEB3D84F810431974803E13E26BF95AF7AB590E17C0113BFE9B36BE12BE16D89273348E0CC094526CAF54ABF8044565EC9500EBF657265474BC362EBDFD78F513282AAF0EEF9BA0BB00F7FF9C7E61F00465BBD379D6201";
const char* pubKey = "AE7DF3EB95DF1F864F86DA9952BB44E760152986731253C96C135E5391AEFF68F5C1640552F1CCC2BA2C12C0C68C051E343B786F13215CEFC8221D9FA97D50E895EAF50D1AF32DC5EB40C9F1F8CA5145B43CEF83F2A89C9661AFA73A70D32951271C6BEFE1B5F24B512520DA7FD4EEC982F2D8057FE1938FA2FB54D8D282A25D8397298B75E154739EF16B8E2F18368F5BEEAD3D18528B9B1A63C731A71735CDB6102E187EF3377B72B58A124FA280891A79A2BD789D5DBA3618BBD74367F5C50A220204D90A59828C3C81FDBD9D2A91CBF6C8563C6FE987BE21B19BBC340DE4D42290D63909AD5D856D13B8CDC91D5701570045CE3609D4F8884F69120AD9A3";
 
void rsa_test(const char* n,const char* d)
{
    RSA* rsa = RSA_new();
 
    BIGNUM* bn = BN_new();
    BIGNUM* bd = BN_new();
    BIGNUM* be = BN_new();
    BN_set_word(be, 0x10001);
    if (n) BN_hex2bn(&bn, n);
 
    if (d) BN_hex2bn(&bd, d);
    RSA_set0_key(rsa, bn, be, bd);
 
    //calc hash
    const char* msg = "hello,rsa!!";
    BYTE shaResult[SHA256_DIGEST_LENGTH] = { 0 };
    SHA256((unsigned char*)msg, strlen(msg), shaResult);
 
    //sign
    unsigned int olen;
    unsigned char sign[256] = { 0 };
    RSA_sign(NID_sha256, shaResult, SHA256_DIGEST_LENGTH, sign, &olen,rsa);
 
    RSA_free(rsa);
}
 
DWORD thread_test(LPVOID lpParam)
{
    rsa_test(pubKey, priKey);
    return 0;
}
 
int main()
{
    //_CrtSetBreakAlloc(159);
 
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
 
    //CreateThread(nullptr, 0, thread_test, nullptr, 0, nullptr);
    //rsa_test(pubKey,priKey);
 
    system("pause");
}

直接在主线程中调用rsa_test(pubKey,priKey)不会导致内存泄漏!

调用 CreateThread(nullptr, 0, thread_test, nullptr, 0, nullptr) 出现内存泄漏!!!

控制台输出如下:

Detected memory leaks!
Dumping objects ->
{173} normal block at 0x000002BDE6D44000, 264 bytes long.
 Data: <   _W- :_ s  ! 6> D8 89 FD 5F 57 2D C5 3A 5F 82 73 F1 00 21 FA 36 
{162} normal block at 0x000002BDE6D43AC0, 264 bytes long.
 Data: <                > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
{161} normal block at 0x000002BDE6D2E2A0, 160 bytes long.
 Data: <`               > 60 F1 0F 91 F6 7F 00 00 00 00 00 00 00 00 00 00 
{160} normal block at 0x000002BDE6D2DBA0, 160 bytes long.
 Data: <`               > 60 F1 0F 91 F6 7F 00 00 00 00 00 00 00 00 00 00 
{159} normal block at 0x000002BDE6D48230, 352 bytes long.
 Data: <        P       > 00 00 00 00 00 00 00 00 50 AB D3 E6 BD 02 00 00 
{158} normal block at 0x000002BDE6D286B0, 12 bytes long.
 Data: <            > 00 00 00 00 00 00 00 00 01 00 00 00 
Object dump complete.

然后我使用_CrtSetBreakAlloc(159)(或其他内存id)定位,这是我的调用堆栈截图: call stack

我的 vs2017 显示断点在 CRYPTO_zalloc(crypto/mem.c)

所以我的问题是如何释放线程中的那些泄漏内存!

非常感谢!!

Download my test code(build with visual studio 2017 x64)

最佳答案

https://www.openssl.org/docs/man1.1.0/man3/OPENSSL_thread_stop.html

    OPENSSL_thread_stop();

会为你做的。你可以像下面这样调用它

DWORD thread_test(LPVOID lpParam)
{
    rsa_test(pubKey, priKey);
    OPENSSL_thread_stop();
    return 0;
}

关于c++ openssl 1.1.1在线程中运行RSA算法导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60088679/

相关文章:

c++ - 在位数组中找到 N 个 1 位的字符串

c++ - 如何使用 std::make_shared 创建基类类型的智能指针?

java - 如何在多线程中处理n个请求

c - 消息队列中的输出被更改/截断

c++ - “Strange”内存泄漏-TCP网络

ios - 我会不会漏水

c++ - 如何从 C++ 中的字符串中删除纯 "\n"?

c++ - 为某些模板参数设置模板函数的公共(public)/私有(private)

java - 必须阅读有关 Java 线程的文章

java - Java Enterprise 应用程序中的类加载问题