title: curl crashes in threaded calls
body: <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>