cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: crash using libcurl 7.19 multi interface

From: Sergii Volchkov <sergii.volchkov_at_gmail.com>
Date: Thu, 2 Apr 2009 14:12:04 +0300

Hello!

On Fri, 13 Mar 2009, Daniel Stenberg wrote:

> I actually recall others in the past that have claimed there are
> problems with the way the threaded resolver works, but we haven't
> sorted anything like that out. Of course one sensible test to do is
> to rebuild libcurl to use c-ares or the synchronous resolver and see
> if that removes the crash.

I have observed exactly the same problem as Hendrik reported earlier,
with the same call stack (although I am using libcurl 7.19.2, but
according to changelogs nothing has been changed in this regard).
According to my analysis, the problem might be with addrinfo_callback
function in hostasyn.c:

      if(data->share)
        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);

      dns = Curl_cache_addr(data, ai,
                            conn->async.hostname,
                            conn->async.port);
      /* ... snip ... */
      if(data->share)
        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);

if several curl requests are added with the same host name (as is the
case in my scenario, and is the case in hendrik's scenario, when he
used fwlink.microsoft.com for all requests), then several
gethostnyname_thread's are created (I set a breakpoint in
gethostbyname_thread and made sure it is called once per each easy
handle despite resolving the same host), and upon resolving the
hostname they are very likely to invoke Curl_cache_addr on the same
host cache simultaneously without thread synchronization, thus
breaking the linked list and other data structures. The only way to
lock those data from simultaneous access is to use a curl share with
CURL_LOCK_DATA_DNS set for all easy handles in use, with appropriate
CURLSHOPT_LOCKFUNC's configured.

In my scenario, my own code was a refactoring of old code using
libcurl; the old code did use curl share interface for easy handles,
and the issue has never been observed.

So, in my opinion, using curl share can be used as a workaround for
the described issue, without a need to use synchronous DNS lookup or
a-res. However, this approach cannot be considered a permanent
solution for libcurl, since CURLSHOPT_SHARE/CURL_LOCK_DATA_DNS states:
"Note that when you use the multi interface, all easy handles added to
the same multi handle will share DNS cache by default without this
having to be used!"

Hope this helps you shed some light on the issue.

Thanks!

--
Sergii Volchkov
Received on 2009-04-02