cURL / Mailing Lists / curl-users / Single Mail

curl-users

libcurl hangs in malloc_consolidate

From: Mark Wattier <mark.wattier_at_gmail.com>
Date: Thu, 22 Mar 2007 16:51:23 -0700

We have a set of wrappers for curl that we have been using in our
application for a long time, but it always would only make one access
in the life of a process. We are now doing something fancier,
involving multiple accesses, and we get this particular problem with
the third access attempt. The program goes into curl_easy_perform, and
never comes out, using 20% of the CPU or more. I kill the process with
signal 11, and it always appears to be in the same place. See core
dump below.

We are using curl 7.15.5, and openssl-0.9.7m. This is on Red Hat
Linux, kernel 2.4.21-15.ELsmp .

Any suggestions would be appreciated.

Core dump:

(gdb) where
#0 0xb73b535d in malloc_consolidate () from /lib/tls/libc.so.6
#1 0xb73b4949 in _int_malloc () from /lib/tls/libc.so.6
#2 0xb73b43f0 in calloc () from /lib/tls/libc.so.6
#3 0xb74a32ae in CreateConnection (data=0x8187188,
in_connect=0xbfff87d8, addr=0xbfff8748, async=0xbfff879a "") at
url.c:2613
#4 0xb74a5287 in Curl_connect (data=0x8187188, in_connect=0xbfff87d8,
asyncp=0xbfff879a "",
    protocol_done=0xbfff879b "\001\200åK·") at url.c:3994
#5 0xb74ae3af in Curl_connect_host (data=0x8187188, conn=0xbfff87d8)
at transfer.c:2133
#6 0xb74ae568 in Curl_perform (data=0x8187188) at transfer.c:2222
#7 0xb74aec88 in curl_easy_perform (curl=0x8187188) at easy.c:470
#8 0x08109d5a in myapp_http_post2 (
    url=0xbfff8cd0 "https://secure1.OBSCURED_URL_WORKS_IN_FIREFOX",
postdata=0x81346c7 "", result=0xbfff8ccc, len=0xbfff8cc8) at
myapp_http.c:1104
#9 0x080ffc50 in remote_site_api_call (
    request=0xbfff8cd0 "https://secure1. OBSCURED_URL_WORKS_IN_FIREFOX
", response=0xbfff8ccc, response_length=0xbfff8cc8) at
remote_site_api.c:78
#10 0x08101702 in remote_site_card_info
(REMOTE_SITE_url_base=0x817d890 "https://secure1.
OBSCURED_URL_WORKS_IN_FIREFOX ", tranid=0x817f4a0 "111",
account=0x81971d0 "050101000144",
    cipher_name=0x817d828 "AES256", encryption_key=0x8173e78 "",
reason_code=0xbfff915c) at remote_site_api.c:668
#11 0x080ff13b in myapp_interface_spc_handle_request (
    request=0xbfff91f0 "<?xml
version=\"1.0\"?>\nOBSCURED_XML_NOT_RELEVANT_TO_PROBLEM"...) at
if_remote_site.c:534
#12 0x0810312f in handle_requests () at ifspc.c:314
#13 0x08102d2d in main (argc=5, argv=0xbfffaac4, envp=0xbfffaadc) at
ifspc.c:225
(gdb)

Relevant code snippets:

 static CURL *curl = NULL;

static struct MemoryStruct chunk;

struct MemoryStruct {

    char *memory;

    size_t size;

};

static size_t WriteMemoryCallback(void *ptr, size_t size, size_t
nmemb, void *data)

{

    register int realsize = size * nmemb;

    struct MemoryStruct *mem = (struct MemoryStruct *) data;

    mem->memory = (char *) realloc(mem->memory, mem->size + realsize + 1);

    if (mem->memory) {

        memcpy(&(mem->memory[mem->size]), ptr, realsize);

        mem->size += realsize;

        mem->memory[mem->size] = 0;

    }

    return realsize;

}

int myapp_http_post2(char *url, char *postdata, char **result, int *len)

{

    CURLcode res;

    int rc;

    MYAPP_DEBUG(0, "%s: entry", FN);

/******************************************************************************

**

** INITIALIZATION

**

\*****************************************************************************/

    MYAPP_DEBUG(0, "%s: init", FN);

    chunk.memory = NULL; /* we expect realloc(NULL, size) to work */

    chunk.size = 0; /* no data at this point */

    *len = 0;

    if (!curl) {

        MYAPP_DEBUG(0, "%s: curl_global_init", FN);

        if ((res = curl_global_init(CURL_GLOBAL_DEFAULT)) != CURLE_OK) {

            http_curl_error(FN, "curl_easy_init", "CURL_GLOBAL_DEFAULT", res);

            return MYAPP_RC_INT_ERR;

        }

        MYAPP_DEBUG(0, "%s: curl_easy_init", FN);

        if ((curl = curl_easy_init()) == NULL) {

            http_curl_error(FN, "curl_easy_init", "", res);

            return MYAPP_RC_INT_ERR;

        }

        MYAPP_DEBUG(0, "%s: myapp_http_set_params", FN);

        if ((rc = myapp_http_set_params(curl)) != MYAPP_RC_INT_OK) {

            return MYAPP_RC_INT_ERR;

        }

/******************************************************************************

**

** CALLBACK FUNCTION

**

\*****************************************************************************/

        /* send all data to this function */

        MYAPP_DEBUG(0, "%s: curl_easy_setopt", FN);

        if ((res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
WriteMemoryCallback)) != CURLE_OK) {

            http_curl_error(FN, "curl_easy_setopt",
"CURLOPT_WRITEFUNCTION", res);

            return MYAPP_RC_INT_ERR;

        }

        /* we pass our 'chunk' struct to the callback function */

        MYAPP_DEBUG(0, "%s: curl_easy_setopt", FN);

        if ((res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)
&chunk)) != CURLE_OK) {

            http_curl_error(FN, "curl_easy_setopt", "CURLOPT_WRITEDATA", res);

            return MYAPP_RC_INT_ERR;

        }

    }

/******************************************************************************

**

** URL

**

\*****************************************************************************/

    MYAPP_DEBUG(0, "%s: curl_easy_setopt", FN);

    if ((res = curl_easy_setopt(curl, CURLOPT_URL, url)) != CURLE_OK) {

        http_curl_error(FN, "curl_easy_setopt", "CURLOPT_URL", res);

        return MYAPP_RC_INT_ERR;

    }

/******************************************************************************

**

** POSTDATA

**

\*****************************************************************************/

    if ((postdata != NULL) && (postdata[0] != '\0')) {

        MYAPP_DEBUG(0, "%s: curl_easy_setopt", FN);

        if ((res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS,
postdata)) != CURLE_OK) {

            http_curl_error(FN, "curl_easy_setopt", "CURLOPT_POSTFIELDS", res);

            return MYAPP_RC_INT_ERR;

        }

    }

/******************************************************************************

**

** FETCH

**

\*****************************************************************************/

    MYAPP_DEBUG(0, "%s: curl_easy_perform", FN);

    if ((res = curl_easy_perform(curl)) != CURLE_OK) {

        http_curl_error(FN, "curl_easy_perform", "curl", res);

        switch (res) {

        case CURLE_OPERATION_TIMEDOUT:

            return MYAPP_RC_INT_TIMEOUT;

        default:

            return MYAPP_RC_INT_ERR;

        }

    }

    MYAPP_DEBUG(0, "%s: curl_easy_perform returned OK", FN);

    /* result is in chunk.memory, size of chunk.size. don't count on
it to be terminated. */

    *result = malloc(chunk.size + 1);

    if (*result == NULL) {

        MYAPP_PANIC(0, "%s: malloc error", FN);

        /* NOTREACHED */

        exit(0);

    }

    MYAPP_DEBUG(0, "%s: malloc OK", FN);

    MYAPP_DEBUG(0, "%s: chunk:%s", FN,chunk.memory);

    memcpy(*result, chunk.memory, chunk.size);

    MYAPP_DEBUG(0, "%s: memcpy OK", FN);

    (*result)[chunk.size] = 0;

    *len = chunk.size;

    MYAPP_DEBUG(0, "%s: result:%s", FN,*result);

/******************************************************************************

**

** REPORTING

**

\*****************************************************************************/

    myapp_http_report(curl, url, myapp_http_post_result);

/******************************************************************************

**

** CLEANUP

**

\*****************************************************************************/

/* NOTE – in this test, persist is turned on so we keep the curl handle */

    if (!HTTP_PROTOCOL_PERSIST) {

        curl_easy_cleanup(curl);

        curl_global_cleanup();

        curl = NULL;

    }

    return MYAPP_RC_INT_OK;

}
Received on 2007-03-23