New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memory leak when timeout expired during POST request #147

Closed
mpromonet opened this Issue Mar 5, 2015 · 2 comments

Comments

Projects
None yet
2 participants
@mpromonet

mpromonet commented Mar 5, 2015

Using a simple example based on postit2.c :

#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
int main(int argc, char *argv[])
{
  CURL *curl;
  CURLcode res;
  struct curl_httppost *formpost=NULL;
  struct curl_httppost *lastptr=NULL;
  struct curl_slist *headerlist=NULL;
  static const char buf[] = "Expect:";

  curl_global_init(CURL_GLOBAL_ALL);
  curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END);
  curl = curl_easy_init();
  headerlist = curl_slist_append(headerlist, buf); 
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:12345");
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);

    res = curl_easy_perform(curl);
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

    curl_easy_cleanup(curl);
    curl_formfree(formpost);
    curl_slist_free_all (headerlist);
  }
  return 0;
}

Starting a netcat command nc -l -p 12345 in order to read HTTP request without answering, running the previous sample under valgrind report the following memory leak :

==7666== 495 (32 direct, 463 indirect) bytes in 1 blocks are definitely lost in loss record 602 of 641
==7666==    at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7666==    by 0x4073BC: AddFormData (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4075BF: AddFormDataf (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x40860D: Curl_getformdata (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x419F99: Curl_http (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4253FA: Curl_do (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4102CE: multi_runsingle (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x4109BC: curl_multi_perform (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x40BB0A: curl_easy_perform (in /mnt/DOWNLOAD/curl/docs/examples/postit2)
==7666==    by 0x40714E: main (in /mnt/DOWNLOAD/curl/docs/examples/postit2)

Investigating show that this was introduced by the commit 1342a96. There is no leak with curl-7_39_0, and there is a leak with curl-7_40_0.

A possible fix seems to add in lib/multi.c line 1019 (in order to free what allocate Curl_getformdata) :

  1018    result = CURLE_OPERATION_TIMEDOUT;
  1019    (void)Curl_done(&data->easy_conn, data->result, TRUE); 
  1020    /* Skip the statemachine and go directly to error handling section. */
  1021    goto statemachine_end;

@bagder bagder self-assigned this Mar 5, 2015

@bagder bagder added the memory-leak label Mar 5, 2015

@bagder

This comment has been minimized.

Member

bagder commented Mar 5, 2015

Thanks, looks like a fine fix to me. Running some local tests to verify nothing breaks.

bagder added a commit that referenced this issue Mar 5, 2015

multi: fix memory-leak on timeout (regression)
Since 1342a96, a timeout detected in the multi state machine didn't
necesarily clear everything up, like formpost data.

Bug: #147
Reported-by: Michel Promonet
Patched-by: Michel Promonet
@bagder

This comment has been minimized.

Member

bagder commented Mar 5, 2015

Thanks, pushed fix as commit 492dfca

@bagder bagder closed this Mar 5, 2015

@lock lock bot locked as resolved and limited conversation to collaborators May 7, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.