curl-users
libcurl hangs in malloc_consolidate
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