我编写了一个简单的curl get包装器来访问http,https内容。如果我用valgrind运行我的测试用例,我可以看到一些仍然可以访问的扇区。是的我知道他们并不像丢失的参考文献那样邪恶或者绝对丢失。但我想保持我的项目清洁。
如果我使用curl_global_init(CURL_GLOBAL_NOTHING)
禁用SSL,则不会检测到memleak。但此后也没有https支持。所以我猜它是一个libcrypt,libssl问题?如果没有valgrind通知,我该怎么做才能正确初始化和清理https curl调用?
jami@jami-mbp:rcc$ valgrind --leak-check=full --show-reachable=yes ./tests/testsuite
==7171== Memcheck, a memory error detector
==7171== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==7171== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==7171== Command: ./tests/testsuite
==7171==
==7171== Conditional jump or move depends on uninitialised value(s)
==7171== at 0x703784B: ASN1_STRING_set (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x702552C: ASN1_mbstring_ncopy (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x7025753: ASN1_mbstring_copy (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x7026614: ASN1_STRING_to_UTF8 (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x7027A42: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x7027FA6: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x702E4E2: ASN1_item_ex_d2i (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x702F09F: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x702F2E7: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x702EB50: ASN1_item_ex_d2i (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x702F09F: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x702F2E7: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171==
OK (3)
==7171==
==7171== HEAP SUMMARY:
==7171== in use at exit: 64 bytes in 2 blocks
==7171== total heap usage: 10,535 allocs, 10,533 frees, 898,726 bytes allocated
==7171==
==7171== 32 bytes in 1 blocks are still reachable in loss record 1 of 2
==7171== at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7171== by 0x6F821FF: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x700A82E: sk_new (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x6D012A9: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==7171== by 0x6D031F8: SSL_COMP_get_compression_methods (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==7171== by 0x6D08618: SSL_library_init (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==7171== by 0x549A1E2: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.2.0)
==7171== by 0x54A1B89: curl_global_init (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.2.0)
==7171== by 0x559240: RCC::IO::HttpClient::get(std::string) (HttpClient.cpp:53)
==7171== by 0x559FFE: HttpClientTest::testBasicRequest() (HttpClientTest.cpp:55)
==7171== by 0x55BB11: CppUnit::TestCaller<HttpClientTest>::runTest() (TestCaller.h:166)
==7171== by 0x56FA081: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
==7171==
==7171== 32 bytes in 1 blocks are still reachable in loss record 2 of 2
==7171== at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7171== by 0x6F821FF: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x700A84C: sk_new (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==7171== by 0x6D012A9: ??? (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==7171== by 0x6D031F8: SSL_COMP_get_compression_methods (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==7171== by 0x6D08618: SSL_library_init (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==7171== by 0x549A1E2: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.2.0)
==7171== by 0x54A1B89: curl_global_init (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.2.0)
==7171== by 0x559240: RCC::IO::HttpClient::get(std::string) (HttpClient.cpp:53)
==7171== by 0x559FFE: HttpClientTest::testBasicRequest() (HttpClientTest.cpp:55)
==7171== by 0x55BB11: CppUnit::TestCaller<HttpClientTest>::runTest() (TestCaller.h:166)
==7171== by 0x56FA081: CppUnit::TestCaseMethodFunctor::operator()() const (in /usr/lib/libcppunit-1.12.so.1.0.0)
==7171==
==7171== LEAK SUMMARY:
==7171== definitely lost: 0 bytes in 0 blocks
==7171== indirectly lost: 0 bytes in 0 blocks
==7171== possibly lost: 0 bytes in 0 blocks
==7171== still reachable: 64 bytes in 2 blocks
==7171== suppressed: 0 bytes in 0 blocks
==7171==
==7171== For counts of detected and suppressed errors, rerun with: -v
==7171== Use --track-origins=yes to see where uninitialised values come from
==7171== ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 2 from 2)
卷曲包装(它的基本部分):
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
std::string HttpClient::get(std::string url)
{
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = NULL;
CURLcode result;
std::string readBuffer = "";
curl = curl_easy_init();
if (curl == 0)
throw std::runtime_error("Unable to create CURL instance");
if (useProxy)
curl_easy_setopt(curl, CURLOPT_PROXY, proxyHost.c_str());
if (useAuth)
authenticate(curl);
if (followRedirect)
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
LOG_DEBUG("http client fetch " + url);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POST, false);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
result = curl_easy_perform(curl);
if (result != CURLE_OK) {
curl_easy_cleanup(curl);
throw std::runtime_error(curl_easy_strerror(result));
}
curl_easy_cleanup(curl);
curl_global_cleanup();
return readBuffer;
}
使用以下命令运行测试:
valgrind --leak-check=full --show-reachable=yes -v ./tests/testsuite
答案 0 :(得分:0)
好的,我接受Joachim Pileborg的好答案(根据主要问题发表评论)。 OpenSSL使用每个进程的一些数据,这些数据在我的程序生命周期中存活。所以valgrind检测到它仍然可以访问,我的OpenSSL初始化/终结似乎是正确的。谢谢Joachim