cURL / Mailing Lists / curl-library / Single Mail

curl-library

Memory leak using multi handle

From: Dan Donahue <ddonahue_at_parallelwireless.com>
Date: Mon, 27 Jun 2016 13:17:06 +0000

Hello,

I am using libcurl 7.44.0 with ssh enabled and am experiencing a memory
leak within libcurl when performing sftp upload/download.

My design uses a singleton C++ class running in a single thread to
perform libcurl upload/download functions. My code works for
uploading/downloading several files simultaneously. The only issue I am
experiencing is the memory leak. I have verified there are no leaks in
my code.

I verified no memory leaks occur when no files are transferred. That
may make me seem like captain obvious, but wanted to confirm I am
calling curl_global_init/cleanup properly.

The attached memdebug trace is what I am seeing after transferring
(upload) one file.

Below is pseudo-code that accurately captures my libcurl calls in
sequence.

To initiate a transfer an easy handle is setup, added to a multi handle
(allocated if need be), and a one time timer is started. When the timer
expires it call myCurlMultiPerform (essentially a wrapper for your
multi perform example). If the the transfer is not complete, then the
timer is re-started. When the the transfer is complete myProcessMsgs()
is called. If the message is done, then cleanup is performed and the
transfer is considered terminated.


/*
 * pseudo-code call sequence
 */
curl_global_init(CURL_GLOBAL_ALL);

multiHandle = curl_multi_init();
easyHandle = curl_easy_init();
curl_multi_add_handle(multiHandle, easyHandle);

/* do upload */
curl_easy_setopt(client->easyHandle, CURLOPT_INTERFACE, intfc);
curl_easy_setopt(client->easyHandle, CURLOPT_URL, url);
curl_easy_setopt(client->easyHandle, CURLOPT_CONNECTTIMEOUT, 30);
curl_easy_setopt(client->easyHandle, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(client->easyHandle, CURLOPT_READDATA, fd);

/* start timer to call myCurlMultiPerform() */
start_onetime_timer();
...

myCurlMultiPerform()
{
    
    curl_multi_fdset(multiHandle, &fdread, &fdwrite, &fdexcep, &maxfd);
    select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); // 1 sec to
    curl_multi_perform(multiHandle, &activeTransfers);

    if (activeTransfers == 0)
        myProcessMsgs(); // done
    else
        start_onetime_timer(); // not done
}

myTimeoutHandler()
{
    myCurlMultiPerform();
}

myProcessMsgs()
{
    while ((msg = curl_multi_info_read(multiHandle, &msgsLeft)))
    {
       if (msg->msg == CURLMSG_DONE)
       {
           if (msg->data.result == CURLE_OK)
               // success
           else
               // error

           myCurlCleanup();
       }
    }
}

myCurlCleanup()
{
    curl_multi_remove_handle(multiHandle, easyHandle);
    curl_easy_cleanup(easyHandle);
    curl_multi_cleanup(multiHandle);
    curl_global_cleanup();

    exit(0);
}

--
Regards,

Dan Donahue

-------------------------------------------------------------------
List admin: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html

Received on 2016-06-27