Valgrind在关闭连接后显示ssl中的内存泄漏

时间:2015-03-12 11:08:44

标签: c++ c linux ssl cryptography

我有一个客户端会不断与服务器通信。 当我通过valgrind运行并得到以下报告时:

以下是我的ssl代码中仍然存在的泄漏。

==6850== 600 bytes in 1 blocks are still reachable in loss record 116 of 118
==6850==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6850==    by 0x50F4D32: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x517DA85: ERR_get_state (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x517DB5D: ERR_put_error (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51AA9DC: PEM_read_bio (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51A8D39: PEM_X509_INFO_read_bio (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51B7A7D: X509_load_cert_crl_file (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51B7BAC: by_file_ctrl (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51AEF2E: X509_STORE_load_locations (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x40AD4A: CloudConnection::establishConnection(int) (CloudConnection.cpp:1046)
==6850==    by 0x409F1C: connectWithCloud() main.cpp:423)
==6850==    by 0x409ADB: main (main.cpp:391)

==6850== 176 bytes in 1 blocks are still reachable in loss record 111 of 118
==6850==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6850==    by 0x50F4D32: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x517A8EF: lh_new (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x50F5FF4: ex_data_check (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x50F6084: def_get_class (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x50F66C8: int_free_ex_data (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x4E70D3C: SSL_free (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==6850==    by 0x40A6AE: CloudConnection::closeConnection() (CloudConnection.cpp:1554)
==6850==    by 0x40D9BB: CloudConnection::receiveData() (CloudConnection.cpp:696)
==6850==    by 0x40DB88: CloudConnection::receiveDataHelper(void*) (CloudConnection.cpp:276)
==6850==    by 0x5477181: start_thread (pthread_create.c:312)
==6850==    by 0x651FFBC: clone (clone.S:111)

以下是我关闭ssl连接的代码段。

    if (ssl) {
        int count = 0;
        while (err != 1) {
            err = SSL_shutdown(ssl);
            if (err != 1) {
                LOGINFO("SSL_shutdown failed");
                count++;
            }
            if (count == 3) {
                LOGINFO("SSL_shutdown failed - final");
                break;
            }
            sleep(1);
        }
    }
    CRYPTO_cleanup_all_ex_data();

    ERR_free_strings();
    ERR_remove_state(0);
    EVP_cleanup();

    if (lockarray) {
        kill_locks();
        lockarray = NULL;
    }
    /* Terminate communication on a socket */
    if (sock) {
        err = close(sock);
        if (-1 == err) {
            LOG(Logger::ERROR, "Could not close the socket. "
                    "Returning error, but also making the structure NULL.");
            //ssl = NULL;
            //return -1;
        }
    }

    /* Free the SSL structure */
    if (ssl) {
        SSL_free(ssl);
        ssl = NULL;
    }

    /* Free the SSL_CTX structure */
    if (ctx) {
        SSL_CTX_free(ctx);
        ctx = NULL;
    }

请注意,记录器是我的自定义库

2 个答案:

答案 0 :(得分:2)

在谷歌搜索了很多,这解决了我的问题

CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
ERR_remove_state(0);
EVP_cleanup();

答案 1 :(得分:0)

我在您的代码中看到您对锁进行了测试:

if (lockarray) ...

其中一个内存泄漏显然来自线程(我们看到它以clone()而不是main()开头)。

这意味着您有多个线程,也可能导致泄漏。

在退出线程之前,您要调用此函数:

ERR_remove_thread_state(0);

在退出应用程序之前,您需要调用此函数以删除锁定的回调:

CRYPTO_set_locking_callback(nullptr);

这应该针对您的情况。