Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leaks in libcurl

After adding the final touches to my program, I ran valgrind to check for memory leaks. And to my surprise, I read that huge chunks of memory were used and never deallocated, although I made sure I freed every resource I was using before ending the program. Looking closely at the report, I find that almost all of the report said the leaks were coming from libcurl function calls. Here's a sample from the report:

==3555== HEAP SUMMARY:
==3555==     in use at exit: 179,937 bytes in 4,212 blocks
==3555==   total heap usage: 18,080 allocs, 13,868 frees, 10,050,116 bytes allocated
==3555== 
==3555== Searching for pointers to 4,212 not-freed blocks
==3555== Checked 486,368 bytes
==3555== 
==3555== 2 bytes in 2 blocks are still reachable in loss record 1 of 667
==3555==    at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3555==    by 0x542C9C9: strdup (in /usr/lib/libc-2.20.so)
==3555==    by 0x4E58C1E: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555==    by 0x4E6A90F: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555==    by 0x4E6B4A0: curl_multi_perform (in /usr/lib/libcurl.so.4.3.0)
==3555==    by 0x404141: url_fopen (network.c:226)
==3555==    by 0x403737: load_tracks (PlayMusic.c:718)
==3555==    by 0x401E1C: main (PlayMusic.c:145)
==3555== 
==3555== 2 bytes in 2 blocks are still reachable in loss record 2 of 667
==3555==    at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3555==    by 0x542C9C9: strdup (in /usr/lib/libc-2.20.so)
==3555==    by 0x4E58C3A: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555==    by 0x4E6A90F: ??? (in /usr/lib/libcurl.so.4.3.0)
==3555==    by 0x4E6B4A0: curl_multi_perform (in /usr/lib/libcurl.so.4.3.0)
==3555==    by 0x404141: url_fopen (network.c:226)
==3555==    by 0x403737: load_tracks (PlayMusic.c:718)
==3555==    by 0x401E1C: main (PlayMusic.c:145)

Here is the url_fopen function that valgrind complains about:

URL_FILE *url_fopen(const char *url, const char *operation)
{
    /*
       this code could check for URLs or types in the 'url' and
       basicly use the real fopen() for standard files 
     */

    URL_FILE *file;

    file = malloc(sizeof(URL_FILE));
    if (!file)
        return NULL;

    memset(file, 0, sizeof(URL_FILE));

    if ((file->handle.file = fopen(url, operation)))
        file->type = CFTYPE_FILE;   /* marked as URL */

    else {
        file->type = CFTYPE_URL;    /* marked as URL */
        file->handle.curl = curl_easy_init();

        curl_easy_setopt(file->handle.curl, CURLOPT_URL, url);
        curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA,
                 file);
        curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE,
                 0L);
        curl_easy_setopt(file->handle.curl,
                 CURLOPT_WRITEFUNCTION,
                 write_callback);

        if (!multi_handle)
            multi_handle = curl_multi_init();

        curl_multi_add_handle(multi_handle,
                      file->handle.curl);

        /*
           lets start the fetch 
         */
        curl_multi_perform(multi_handle,
                   &file->still_running);

        if ((file->buffer_pos == 0) && (!file->still_running)) {
            /*
               if still_running is 0 now, we should return NULL 
             */

            /*
               make sure the easy handle is not in the multi handle anymore 
             */
            curl_multi_remove_handle(multi_handle,
                         file->handle.curl);

            /*
               cleanup 
             */
            curl_easy_cleanup(file->handle.curl);
            curl_multi_cleanup(multi_handle);
            fclose
            free(file);

            file = NULL;
        }
    }
    return file;
}

Are these just false positives ? If they are, how can I force valgrind to ignore them. If they are not, is there a solution to this leaking problem ?

like image 897
Amr Ayman Avatar asked Jan 24 '15 15:01

Amr Ayman


People also ask

How do I see memory leaks in IE11?

Run the demo plunker in IE11. Hit F12 and go to the memory tab and start the memory analyzer. Additionally you can open Task Manger in Windows and watch the Memory Usage.

Can you have memory leak in JS?

JavaScript code can experience memory leaks by keeping hidden references to objects. Hidden references can cause memory leaks in many unexpected ways.

Does console log cause memory leak?

console. log() causes memory leaks but only when the console is opened. Normally users do not open the console. So it is totally safe to print any huge objects to the console.


1 Answers

Try using curl_global_init(CURL_GLOBAL_DEFAULT); at the start of the program. This sets the environment that libcURL requires.

It is recommended that, this function must be called at least once within a program. Also it is not thread-safe so it must be called at the very beginning of the program, before any threads start.

Also you should call curl_global_cleanup(); once for each call to curl_global_init(), at the end of the program when you are done using libcURL. This will clean up all things used by libcURL.

like image 121
akhileshmoghe Avatar answered Oct 20 '22 01:10

akhileshmoghe