>
> Chugs along for hundreds of thousands of HTTP request/responses and then
> bang....
>
> Similar core backtraces:
>
> (gdb) bt
> #0  Curl_splay (i={tv_sec = 1624023, tv_usec = 680044}, t=0x0) at
> splay.c:53
> #1  0x0015b200 in Curl_splaygetbest (i={tv_sec = 1624023, tv_usec =
> 680044},
> t=0x9f309e0,
>    removed=0xb61cf18c) at splay.c:213
> #2  0x00153c1f in curl_multi_perform (multi_handle=0x954506c,
> running_handles=0xb61cf37c)
>    at multi.c:1607
> #3  0x00aece88 in http_client_send_request () at http_client.c:488
> #4  0x0804c1ca in http_client_loop (arg=0x0) at ussdmain.c:493
> #5  0x009a43cc in start_thread () from /lib/tls/libpthread.so.0
> #6  0x005e4f0e in clone () from /lib/tls/libc.so.6
> (gdb)
>
> (gdb) bt
> #0  Curl_splay (i={tv_sec = 1628422, tv_usec = 184510}, t=0xa440c80) at
> splay.c:57
> #1  0x00354200 in Curl_splaygetbest (i={tv_sec = 1628422, tv_usec =
> 184510},
> t=0xa440c80,
>    removed=0xb61b218c) at splay.c:213
> #2  0x0034cc1f in curl_multi_perform (multi_handle=0xa37606c,
> running_handles=0xb61b237c)
>    at multi.c:1607
> #3  0x00748e73 in http_client_send_request () at http_client.c:488
> #4  0x0804c1ca in http_client_loop (arg=0x0) at ussdmain.c:493
> #5  0x009a43cc in start_thread () from /lib/tls/libpthread.so.0
> #6  0x00914f0e in clone () from /lib/tls/libc.so.6
> (gdb)
>
> Pseudo-code : Using multi-interface (Leaving out error handling for
> clarity):
>
> Thread #1
> Function #1 : Initialization function and settings that shall apply to all
> connections.
> curl_global_init(CURL_GLOBAL_
> ALL);
> multi_handle = curl_multi_init();
> for(i=0; i<configured_number_of_connections; i++)
> {
>    client_connection_array[i].easy_handle = curl_easy_init();
>    curl_easy_setopt(client_connection_array[i].easy_handle,
> CURLOPT_TIMEOUT, transmission_timeout);
>    curl_easy_setopt(client_connection_array[i].easy_handle,
> CURLOPT_CONNECTTIMEOUT, connection_timeout);
> }
> curl_easy_setopt(client_connection_array[i].easy_handle, CURLOPT_NOSIGNAL,
> 1L);
>
> Function #2 : Create POST bundle function.
> curl_easy_setopt(  client_connection_array[i].easy_handle,CURLOPT_URL,
> .client_connection_array[i].config.url);
> curl_easy_setopt(  client_connection_array[i].easy_handle, CURLOPT_POST,
> TRUE);
> curl_easy_setopt(  client_connection_array[i].easy_handle,
> CURLOPT_POSTFIELDSIZE,
> strlen(client_connection_array[i].config.request_payload);
> curl_easy_setopt(  client_connection_array[i].easy_handle,
> CURLOPT_POSTFIELDS, client_connection_array[i].config.request_payload);
> curl_easy_setopt(  client_connection_array[i].easy_handle,
> CURLOPT_WRITEFUNCTION, write_data);
> curl_easy_setopt(  client_connection_array[i].easy_handle,
> CURLOPT_WRITEDATA, &client_connection_array[i].read_response);
> curl_multi_add_handle(multi_handle,
> client_connection_array[i].easy_handle);
>
> Function #3 :Shutdown
> for(i=0; i<configured_number_of_connections; i++)
> {
>    if(NULL != client_connection_array[i].easy_handle)
>    {
>        curl_multi_remove_handle(    multi_handle,
> client_connection_array[i].easy_handle);
>        curl_easy_cleanup(client_connection_array[i].easy_handle);
>    }
> }
> curl_multi_cleanup(multi_handle);
> free(client_connection_array);
>
> Thread #2 - Called every 10ms
> Function #1 :
>    while(CURLM_CALL_MULTI_PERFORM ==
>        curl_multi_perform(multi_handle, &still_running));
>
>    while(still_running)
>    {
>        if((++iterate)>TUNING_ITERATIONS) break;
>
>        struct timeval timeout;
>        int rc; /* select() return code */
>
>        fd_set fdread;
>        fd_set fdwrite;
>        fd_set fdexcep;
>        int maxfd;
>
>        FD_ZERO(&fdread);
>        FD_ZERO(&fdwrite);
>        FD_ZERO(&fdexcep);
>
>        /* set a suitable timeout to play around with */
>        timeout.tv_sec = 1;
>        timeout.tv_usec = 0;
>
>        /* get file descriptors from the transfers */
>        curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
>        rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
>
>        switch(rc) {
>            case -1:
>                /* select error */
>            break;
>            case 0:
>                /* timeout, do something else */
>            break;
>            default:
>                /*  One or more of curl's file descriptors say there's
>                    data to read or write */
>                while(CURLM_CALL_MULTI_PERFORM ==
>                    curl_multi_perform(multi_handle, &still_running));
>                break;
>        }
>    }
>
> while ((msg = curl_multi_info_read(multi_handle, &msgs_left)))
>    {
>        if(msg->msg == CURLMSG_DONE)
>        {
>            /* Find out which handle this message is about */
>            for(idx=0; idx<configured_number_of_connections; idx++)
>            {
>                found =
>                    ((msg->easy_handle ==
> client_connection_array[idx].easy_handle)
>                    && (client_connection_array[idx].state == BUSY));
>
>                if(found)
>                    break;
>            }
>
>            if((msg->data.result == CURLE_OK) && (found))
>            {
>                client_process_response pr =
>                    client_connection_array[idx].config.response_callbk;
>
>                (*pr)( client_connection_array[idx].read_response.writeptr,
>
> client_connection_array[idx].read_response.write_size);
>            }
>            else if((msg->data.result == CURLE_OPERATION_TIMEOUTED) &&
> (found))
>            {
>                timeout_client_connection_notify tn =
>
> client_connection_array[idx].config.timeout_client_callbk;
>
>                (*tn)(
> client_connection_array[idx].config.destination_module,
>
> client_connection_array[idx].config.destination_instance);
>            }
>            else
>            {
>                client_request_failure rf =
>
> client_connection_array[idx].config.failure_client_callbk;
>
>                (*rf)(
> client_connection_array[idx].config.destination_module,
>
> client_connection_array[idx].config.destination_instance);
>            }
>
>            if((resm=curl_multi_remove_handle(multi_handle,
>                client_connection_array[idx].easy_handle)))
>            {
>                printf("Failed to remove easy handle from multi-stack, ret
> %d\n",
>                    resm);
>            }
>
>            client_connection_array[idx].state = IDLE;
>
>            if(NULL != client_connection_array[idx].read_response.writeptr)
>                free(client_connection_array[idx].read_response.writeptr);
>        }
>    }
>

Has anyone seen a core like this before? From a user perspective, does it
indicate a particular usage of the API that I've implemented incorrectly or
indicate a particular area where I should focus on?
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to