cURL / Mailing Lists / curl-library / Single Mail

curl-library

Segmenation Fault in libcurl

From: Rilium <rilium_at_mail.ru>
Date: Mon, 27 Apr 2009 02:45:07 +0400

Hello

I found that my application using libcurl has "stable" crashes while
accessing one server
Application uses libcurl with multi interface, without share interface.
Only one program thread is used.
It provides g_malloc and other glib memory functions to libcurl with
curl_global_init_mem(CURL_GLOBAL_ALL,...).
It add's multiple easy handles to multi handle, for each handle this
options is set:
/* safe_curl_easy_setopt - just wrapper that terminate execution in case
of error */
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_ERRORBUFFER,
                                          
url_client->curl_error_description); // Uniq and valid for each easy
handle, has size CURL_ERROR_SIZE
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_FAILONERROR, 1l);
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_NOSIGNAL, 1l);
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_ENCODING, "");

    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_USERAGENT,
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
    long redirects_enabled = 0;
    safe_curl_easy_setopt(url_client->curl_handle,
CURLOPT_FOLLOWLOCATION, redirects_enabled);
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_MAXREDIRS, 0);
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_COOKIE, NULL);

    safe_curl_easy_setopt(url_client->curl_handle,
CURLOPT_WRITEFUNCTION, ...);
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_WRITEDATA, ...);
    // Some http or https url
    safe_curl_easy_setopt(url_client->curl_handle, CURLOPT_URL, ...);

Each handle is added with curl_multi_add_handle().
after any transfer ended, curl_multi_info_read() used to read messages.
than for each easy handle curl_multi_remove_handle,
curl_multi_add_handle, CURLOPT_URL are called
Transfers is done with curl_multi_perform()

Bug happen's not with any server, only with nearly 5-7% of them, and
only when it uses lot of easy handle(minimum that i saw - 30),
mainly at happen's after 300-700 successfull transfer's

First of all i detected one of problematic server, than runned
application under gdb, after segfault it showed me this backtrace:

[New Thread 0xb777c8e0 (LWP 31502)]
Total parsed: 734 Last: http://********
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb777c8e0 (LWP 31502)]
0xb7f719cb in Curl_pgrsTime (data=0x0, timer=TIMER_CONNECT) at
progress.c:172
172 progress.c: No such file or directory.
    in progress.c
(gdb) bt
#0 0xb7f719cb in Curl_pgrsTime (data=0x0, timer=TIMER_CONNECT) at
progress.c:172
#1 0xb7f94f01 in checkPendPipeline (conn=0x8b76978) at multi.c:1983
#2 0xb7f950e6 in multi_runsingle (multi=0x8aa8248, easy=0x8b2f230) at
multi.c:1337
#3 0xb7f95cb9 in curl_multi_perform (multi_handle=0x8aa8248,
running_handles=0xbf8cd838) at multi.c:1460
*
*
*
*
*
*
*
) at *

I checked libcurl code, and found, that it tries to access data, while
it is NULL, but this error were not stable
Than i started application this way:

G_SLICE=always-malloc valgrind --show-reachable=yes --malloc-fill=ff
--free-fill=ff --suppressions=./supp.txt --leak-check=full

And three times one by one, get same output without any diffrent's
except count of successfull transfers(it's order is not fixed),
error always happen's on diffrent pages

Invalid write of size 4
==32001== at 0x405802F: multi_runsingle (multi.c:907)
==32001== by 0x4058CB8: curl_multi_perform (multi.c:1460)
*
*
*
*
*
*
*
==32001== Address 0x4ed88e8 is 0 bytes inside a block of size 924 free'd
==32001== at 0x4022B8A: free (vg_replace_malloc.c:323)
==32001== by 0x40B1445: g_free (gmem.c:190)
==32001== by 0x404373B: conn_free (url.c:2164)
==32001== by 0x4043870: Curl_disconnect (url.c:2239)
==32001== by 0x4045D26: CreateConnection (url.c:2528)
==32001== by 0x4045E2E: Curl_connect (url.c:4384)
==32001== by 0x4058728: multi_runsingle (multi.c:926)
==32001== by 0x4058CB8: curl_multi_perform (multi.c:1460)
*
*
*
*
*
*
*
==32001==
==32001== Invalid read of size 4
==32001== at 0x40580C9: multi_runsingle (multi.c:1334)
==32001== by 0x4058CB8: curl_multi_perform (multi.c:1460)
*
*
*
*
*
*
*
==32001== Address 0x4ed8a8c is 420 bytes inside a block of size 924 free'd
==32001== at 0x4022B8A: free (vg_replace_malloc.c:323)
==32001== by 0x40B1445: g_free (gmem.c:190)
==32001== by 0x404373B: conn_free (url.c:2164)
==32001== by 0x4043870: Curl_disconnect (url.c:2239)
==32001== by 0x4045D26: CreateConnection (url.c:2528)
==32001== by 0x4045E2E: Curl_connect (url.c:4384)
==32001== by 0x4058728: multi_runsingle (multi.c:926)
==32001== by 0x4058CB8: curl_multi_perform (multi.c:1460)
*
*
*
*
*
*
*
==32001==
==32001== Invalid read of size 4
==32001== at 0x40434A8: Curl_removeHandleFromPipeline (url.c:2302)
==32001== by 0x40580DD: multi_runsingle (multi.c:1334)
==32001== by 0x4058CB8: curl_multi_perform (multi.c:1460)
*
*
*
*
*
*
*
==32001== Address 0xffffffff is not stack'd, malloc'd or (recently) free'd
==32001==
==32001== Process terminating with default action of signal 11 (SIGSEGV)
==32001== General Protection Fault
==32001== at 0x40434A8: Curl_removeHandleFromPipeline (url.c:2302)
==32001== by 0x40580DD: multi_runsingle (multi.c:1334)
==32001== by 0x4058CB8: curl_multi_perform (multi.c:1460)
*
*
*
*
*
*
*
=================================================================================

I assume, that this is memory corruption in libcurl(my application
doesn't generate any warnings in valgrind)
Also notable, that if i change memory filling to 61, segfault message
changes to
==32325== Process terminating with default action of signal 11 (SIGSEGV)
==32325== Access not within mapped region at address 0x61616161

Server where this debugging were done:

Debian lenny

Linux * 2.6.26-1-686 #1 SMP Sat Jan 10 18:29:31 UTC 2009 i686 GNU/Linux

||/ Name Version
Description
+++-=================================-=================================-==================================================================================
ii libc6 2.7-18
GNU C Library: Shared libraries
ii libcurl3 7.18.2-8lenny2
Multi-protocol file transfer library (OpenSSL)

============================================================================================

I have feeling, that this happens, when part of connections is left in
TIME_WAIT, or faied, but i'm not sure about it.
If any more information is nessecary, please, let me know.

With best regards, Klimentov Konstantin.

P.S. Sorry for filling part of information with *, but code is private
and doesn't distributed away from my company, so i doesn't have
permissions to publish it anywhere.
Received on 2009-04-27