curl crashes in threaded calls
<p>I read the SO articles if <code>curl</code> is thread-safe. This very simple code crashes - not always but when I call the program several times in a row [not parallel] then it crashes either with a segmentation fault or with the below error.</p>

<p>That far I am convinced I follow the rules regarding <code>curl</code> and threads as stated in the documentation.</p>

<p>In tests I could find out that it crashes in <code>curl_easy_perform()</code>.</p>

<pre><code>#include &lt;curl/curl.h&gt;
#include &lt;stdio.h&gt;
#include &lt;thread&gt;

class curlClass
{
private:
    CURL * curl {};
    CURLcode res;
    const char * sUrl;

public:
    auto loadDataFromUrl()     -&gt; void;
    static auto initCurl()     -&gt; void;
    static auto releaseCurl()  -&gt; void;
    static auto callbackSaveData( void * content, size_t size, size_t nmemb, curlClass * classInstance ) -&gt; size_t;
    curlClass( const char * );
    ~curlClass();
};

auto curlClass::initCurl() -&gt; void
{
    curl_global_init(CURL_GLOBAL_SSL);
}

auto curlClass::releaseCurl() -&gt; void
{
    curl_global_cleanup();
}

curlClass::curlClass( const char * sUrl ) : sUrl( sUrl )
{
    curl = curl_easy_init();
}

curlClass::~curlClass()
{
    curl_easy_cleanup( curl );
}

auto curlClass::callbackSaveData( __attribute__ ((unused))  void *contents, 
    size_t size, 
    size_t nmemb, 
    __attribute__ ((unused))    curlClass * classInstance
) -&gt; size_t
{
    return size * nmemb;
}

auto curlClass::loadDataFromUrl() -&gt; void
{
    if ( curl )
    {
        curl_easy_setopt(curl, (CURLoption) CURLOPT_SSL_VERIFYPEER, nullptr);
        curl_easy_setopt(curl, (CURLoption) CURLOPT_URL, sUrl);
        curl_easy_setopt(curl, (CURLoption) CURLOPT_WRITEFUNCTION, callbackSaveData);
        res = curl_easy_perform(curl);
        printf( "Return: %d\n", res );
    }
}

auto worker( const char * sUrl ) -&gt; void
{
    curlClass myInstance( sUrl );
    myInstance.loadDataFromUrl();
}

int main(void)
{
    curl_version_info_data * curl_version = curl_version_info(CURLVERSION_NOW);

    printf( "Curl version=%s\n", curl_version-&gt;version );
    curlClass::initCurl();

    std::thread thread1( worker, "https://www.google.com");
    std::thread thread2( worker, "https://www.google.com" );
    std::thread thread3( worker, "https://www.google.com" );
    std::thread thread4( worker, "https://www.google.com" );
    std::thread thread5( worker, "https://www.google.com" );
    std::thread thread6( worker, "https://www.google.com" );
    std::thread thread7( worker, "https://www.google.com" );

    thread1.join();
    thread2.join();
    thread3.join();
    thread4.join();
    thread5.join();
    thread6.join();
    thread7.join();

    curlClass::releaseCurl();
}
</code></pre>

<p><strong>UPDATE:</strong></p>

<p>I compiled the new <code>curl</code> version <code>7.46.0</code>. This is one of the possible error dumps:</p>

<pre><code>Curl version=7.46.0
*** glibc detected *** ./curl_crash: double free or corruption (out): 0x00007fcd200056d0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x76618)[0x7fcd2ff4a618]
/lib64/libc.so.6(cfree+0x6c)[0x7fcd2ff4f65c]
/usr/lib64/libcrypto.so.0.9.8(CRYPTO_free+0x19)[0x7fcd2f9f13f9]
/usr/lib64/libcrypto.so.0.9.8(+0xf407d)[0x7fcd2f9d307d]
/usr/lib64/libcrypto.so.0.9.8(ERR_clear_error+0xd)[0x7fcd2f9efd1d]
/usr/local/lib/libcurl.so.4(+0x4849c)[0x7fcd30a2d49c]
/usr/local/lib/libcurl.so.4(+0x4b970)[0x7fcd30a30970]
/usr/local/lib/libcurl.so.4(+0x1073d)[0x7fcd309f573d]
/usr/local/lib/libcurl.so.4(+0x20451)[0x7fcd30a05451]
/usr/local/lib/libcurl.so.4(+0x31e0e)[0x7fcd30a16e0e]
/usr/local/lib/libcurl.so.4(curl_multi_perform+0xdd)[0x7fcd30a1780d]
/usr/local/lib/libcurl.so.4(curl_easy_perform+0x10b)[0x7fcd30a1001b]
./curl_crash(_ZN9curlClass15loadDataFromUrlEv+0x88)[0x408002]
./curl_crash(_Z6workerPKc+0x2c)[0x408051]
./curl_crash(_ZNSt12_Bind_simpleIFPFvPKcES1_EE9_M_invokeIILm0EEEEvSt12_Index_tupleIIXspT_EEE+0x40)[0x409818]
./curl_crash(_ZNSt12_Bind_simpleIFPFvPKcES1_EEclEv+0x1d)[0x409711]
./curl_crash(_ZNSt6thread5_ImplISt12_Bind_simpleIFPFvPKcES3_EEE6_M_runEv+0x1c)[0x40968e]
/usr/local/lib64/libstdc++.so.6(+0xb5c10)[0x7fcd30790c10]
/lib64/libpthread.so.0(+0x77f6)[0x7fcd2e81c7f6]
/lib64/libc.so.6(clone+0x6d)[0x7fcd2ffaf09d]
======= Memory map: ========
</code></pre>

<p>I do not have really a clue what is going wrong. When I start the program 5 times then at least once it crashes.</p>

<p>What am I doing wrong or is it possible - according to the dump - that I am using an old SSL library?</p>

<p>Command line to compile:</p>

<p><code>g++ --std=c++11 -Wall -Werror -pedantic -Wextra curl_crash.cpp -o curl_crash -lcurl -rdynamic &amp;&amp; ./curl_crash</code></p>