curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: Libcurl curl_slist_append() leads to memory leak.

From: Timothe Litt <litt_at_acm.org>
Date: Fri, 22 Apr 2022 09:39:58 -0400

Besides not calling curl_slist_free_all() per

list_append.html
>
> The list should be freed again (after usage) withcurl_slist_free_all
> <https://curl.se/libcurl/c/curl_slist_free_all.html>.
>
>
(Someone beat me to pointing that out...)

If the code shown is complete, you're not using the headers - you're
passing a NULL pointer to curl_easy_setopt(). I expect that a trace (or
verbose output) will show that they aren't being sent.  "Seems to work"
and "does work" are two different things...

Note under "Return value" that the call can fail and that the return
value is a new list pointer.  See the example for proper handling, which
requires an intermediate variable as well as updating the list pointer
to avoid leaks.

--
Timothe Litt
ACM Distinguished Engineer
--------------------------
This communication may not represent the ACM or my employer's views,
if any, on the matters discussed.


On 22-Apr-22 09:10, Iku_ex Diaz via curl-library wrote:
> *System*
> x86 with Linux Ubuntu 22.04
>
> *Problem*
> I'm running a program that uses libcurl to perform 3 requests, one
> GET, and two PUT. Using /Valgrind /outputs several memory leaks
> originated at the /curl_slist_append() /calls for the two PUT requests.
>
> *TRACE:*
> ==15078== HEAP SUMMARY:
> ==15078== in use at exit: 1,428 bytes in 72 blocks ==15078== total
> heap usage: 8,310 allocs, 8,238 frees, 1,512,884 bytes allocated
> ==15078== ==15078== 124 (64 direct, 60 indirect) bytes in 4 blocks are
> definitely lost in loss record 5 of 12 ==15078== at 0x483B7F3: malloc
> (in
> /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==15078== by 0x48A034D: ??? (in
> /usr/lib/x86_64-linux-gnu/libcurl.so.4.6.0) ==15078== by 0x48A03BC:
> curl_slist_append (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.6.0)
> ==15078== by 0x1149CD:
> DLMController::liberateClient(std::__cxx11::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> std::__cxx11::basic_string<char, std::char_traits<char>,
> std::allocator<char> >) (dlmController.cpp:598) ==15078== by 0x113F82:
> DLMController::stopDLM() (dlmController.cpp:466) ==15078== by
> 0x160259: main (in
> /home/ikerdiaz/Desktop/dlm/embedded_load_manager/dlm) ==15078==
> ==15078== 164 (64 direct, 100 indirect) bytes in 4 blocks are
> definitely lost in loss record 6 of 12 ==15078== at 0x483B7F3: malloc
> (in
> /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==15078== by 0x48A034D: ??? (in
> /usr/lib/x86_64-linux-gnu/libcurl.so.4.6.0) ==15078== by 0x48A03BC:
> curl_slist_append(in /usr/lib/x86_64-linux-gnu/libcurl.so.4.6.0)
> ==15078== by 0x1149A1:
> DLMController::liberateClient(std::__cxx11::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> std::__cxx11::basic_string<char, std::char_traits<char>,
> std::allocator<char> >) (dlmController.cpp:596) ==15078== by 0x113F82:
> DLMController::stopDLM() (dlmController.cpp:466) ==15078== by
> 0x160259: main (in
> /home/ikerdiaz/Desktop/dlm/embedded_load_manager/dlm) ==15078==
> ==15078== 188 (64 direct, 124 indirect) bytes in 4 blocks are
> definitely lost in loss record 7 of 12 ==15078== at 0x483B7F3: malloc
> (in
> /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==15078== by 0x48A034D: ??? (in
> /usr/lib/x86_64-linux-gnu/libcurl.so.4.6.0) ==15078== by 0x48A03BC:
> curl_slist_append(in /usr/lib/x86_64-linux-gnu/libcurl.so.4.6.0)
> ==15078== by 0x1149B7:
> DLMController::liberateClient(std::__cxx11::basic_string<char,
> std::char_traits<char>, std::allocator<char> >,
> std::__cxx11::basic_string<char, std::char_traits<char>,
> std::allocator<char> >) (dlmController.cpp:597) ==15078== by 0x113F82:
> DLMController::stopDLM() (dlmController.cpp:466) ==15078== by
> 0x160259: main (in /home/ikerdiaz/Desktop/dlm/embedded_load_manager/dlm)
> The trace is larger. There is always this same leak whenever there is
> a call to /curl_slist_append(). /The code generating the trace above
> is the following one (where the lines in orange in the /Valgrind
> /trace are the calls to curl_slist_append).
> **
> *CODE:*
> void DLMController::liberateClient(std::string dev_id, std::string ip)
> { // Payload nlohmann::json free_payload = { {"device", { {"id",
> dev_id} } } }; std::string tmp_str = free_payload.dump(4); const char*
> put_data = tmp_str.c_str(); CURL* curl; CURLcode res; std::string
> route = ip + "/services/cpi/dlmLimitReset.json"; const char* ip_dir =
> route.c_str(); curl = curl_easy_init(); struct curl_slist* headers =
> NULL; curl_slist_append(headers, "Accept: application/json"); //
> MEMORY LEAKcurl_slist_append(headers, "Content-Type:
> application/json"); //MEMORY LEAKcurl_slist_append(headers, "charset:
> utf-8"); //MEMORY LEAK curl_easy_setopt(curl, CURLOPT_URL, ip_dir);
> curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
> curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
> curl_easy_setopt(curl, CURLOPT_POSTFIELDS, put_data); // CALL res =
> curl_easy_perform(curl); // Check for errors. if (res != CURLE_OK) {
> std::cout << curl_easy_strerror(res) << std::endl; } // Check return
> code long httpCode(0); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
> &httpCode); curl_easy_cleanup(curl); if (httpCode != 204 && httpCode
> != 200) { std::cout << "Fail, returned code: " << httpCode <<
> std::endl; } }
>
>
> Please note that even if /curl_global_init(0)/ and
> /curl_global_cleanup()/ don't appear in the function, they are called
> in another part of the code before this function is called. This is
> done once as explained in the documentation. The code does work,
> meaning that the request is successful and works just fine, although
> there is this memory leak.
> I would highly appreciate it if someone could help me figure this out.
> Thank you!
> Iker
>

-- 
Unsubscribe: https://lists.haxx.se/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html
Received on 2022-04-22