title: curl_easy_perform segmentation fault on Linux
body: <p>I am working on a c++ app which uses curl in order to an HTTP GET request. It works perfectly fine on Windows but on Linux (CentOS 7) I get a segmentation fault when curl_easy_cleanup is used. </p>
  
  <p>Below is my code</p>
  
  <pre><code>CURL* curl = NULL;
      curl = curl_easy_init();
  
      if (curl == NULL)
      {
  
          this-&gt;getBitsLibrary()-&gt;writeToLog("Failed to init curl");
          this-&gt;getBitsLibrary()-&gt;setAlarm("CrashInfo", Alarms::AlarmLevel::Critical, "Failed to init curl for IP lookup");
          return;
      }
  
      stringstream urlstream;
      string iplookupURL;
      //curlResponse = "";
      urlstream &lt;&lt; StaticSettings::IP_Lookup::ipLookupURL &lt;&lt; "/" &lt;&lt; clientIP &lt;&lt; "?access_key="&lt;&lt;StaticSettings::IP_Lookup::api_key;
      iplookupURL = urlstream.str();
      logstream &lt;&lt; "Using URL " &lt;&lt; iplookupURL &lt;&lt; " for IP lookup";
      this-&gt;getBitsLibrary()-&gt;writeToLog(logstream.str(), "CrashInfo", "performIPLookup");
      logstream.clear();
      logstream.str(string());
      //string response = "";
      this-&gt;curlResponse = new string();
      curl_easy_setopt(curl, CURLOPT_URL, iplookupURL.c_str());
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)this);
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &amp;curlStaticCallback);
  
  
  
      CURLcode res = curl_easy_perform(curl);
  if (res != CURLE_OK)
      {
          logstream &lt;&lt; "Failed to perform IP lookup using curl";
          this-&gt;getBitsLibrary()-&gt;writeToLog(logstream.str(), "CrashInfo", "performIPLookup");
          this-&gt;getBitsLibrary()-&gt;setAlarm("CrashInfo", Alarms::AlarmLevel::Warning, "Failed to perform IP Lookup. Curl error");
          curl_easy_cleanup(curl);
          return;
      }
  
      int httpResponseCode = 0;
      curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &amp;httpResponseCode);
      if (httpResponseCode == 200)
      {
  
          if (!this-&gt;curlResponse-&gt;empty())
          {
              this-&gt;getBitsLibrary()-&gt;writeToLog("Processing response for IP lookup");
              rapidjson::Document jsonObject;
              jsonObject.Parse(this-&gt;curlResponse-&gt;c_str());
  
              const rapidjson::Value&amp; countryValue = jsonObject["country_name"];
              if (!countryValue.IsNull())
              {
                  string country = string(jsonObject["country_name"].GetString());
                  this-&gt;setCountry(!country.empty() ? country : "N/A");
              }
              else
              {
                  this-&gt;setCountry("N/A");
              }
  
              const rapidjson::Value&amp; cityValue = jsonObject["city"];
              if (!cityValue.IsNull())
              {
                  string city = string(jsonObject["city"].GetString());
                  this-&gt;setCity(!city.empty() ? city : "N/A");
              }
              else
              {
                  this-&gt;setCity("N/A");
              }
  
              this-&gt;getBitsLibrary()-&gt;writeToLog("IPLookup performed successfully", "CrashInfo", "performIPLookup");
          }
  delete this-&gt;curlResponse;
      this-&gt;curlResponse = NULL;
      curl_easy_cleanup(curl);
  </code></pre>
  
  <p>Due the curl being a C library, I've created a static function (outside of the C++ class) as follows:</p>
  
  <pre><code>size_t curlStaticCallback(void *contents, size_t size, size_t nmemb, void * userp)
  {
      CrashInfo *crashInfo = (CrashInfo*)userp;
      crashInfo-&gt;curlResponseWriteCallback(contents, size, nmemb, userp);
      return size * nmemb;
  }
  </code></pre>
  
  <p>The above static function called by the WRITEFUNCTION in curl. I get the class object and then call the C++ function which is as follows:</p>
  
  <pre><code>size_t CrashInfo::curlResponseWriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
  {
      curlResponse-&gt;append((char*)contents, size * nmemb);
      return size * nmemb;
  }
  </code></pre>
  
  <p>As mentioned above, this works perfectly fine on Windows but on Linux it works fine where I get the expected response the URL, but when <code>curl_easy_cleanup</code> is called I then get a segmentation fault which contains the following stack:</p>
  
  <pre><code>#0  0x00007fe7f45ff2ad in ?? () from /lib64/libstdc++.so.6
  #1  0x00007fe7f4661c03 in std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;::~basic_string() () from /lib64/libstdc++.so.6
  #2  0x000000000043f773 in WebManager::CrashInfo::performIPLookup (this=0x7fe7d00020d0, clientIP="192.168.1.96") at CrashInfo.cpp:732
  #3  0x000000000043aeb0 in WebManager::CrashInfo::processCrashInfo (this=0x7fe7d00020d0, httpRequest=0x7fe7d00008f0) at CrashInfo.cpp:308
  #4  0x00000000004396ee in WebManager::CrashInfo::CrashInfo (this=0x7fe7d00020d0, httpRequest=0x7fe7d00008f0) at CrashInfo.cpp:50
  #5  0x000000000046ce23 in WebManager::WebProcessor::processWebSocketData (this=0x7fe7ed841a60, clientpointer=0x7fe7e40008c0, ipAddress=0x7fe7ed8426b8 "192.168.1.96") at WebProcessor.cpp:71
  #6  0x0000000000473bd6 in std::_Mem_fn&lt;void (WebManager::WebProcessor::*)(void*, char*)&gt;::operator()&lt;int*, char*, void&gt;(WebManager::WebProcessor*, int*&amp;&amp;, char*&amp;&amp;) const (this=0x7fe7e4000948, __object=0x7fe7ed841a60)
      at /usr/include/c++/4.8.2/functional:601
  #7  0x00000000004739fd in std::_Bind_simple&lt;std::_Mem_fn&lt;void (WebManager::WebProcessor::*)(void*, char*)&gt; (WebManager::WebProcessor*, int*, char*)&gt;::_M_invoke&lt;0ul, 1ul, 2ul&gt;(std::_Index_tuple&lt;0ul, 1ul, 2ul&gt;) (this=0x7fe7e4000930)
      at /usr/include/c++/4.8.2/functional:1732
  #8  0x00000000004737fd in std::_Bind_simple&lt;std::_Mem_fn&lt;void (WebManager::WebProcessor::*)(void*, char*)&gt; (WebManager::WebProcessor*, int*, char*)&gt;::operator()() (this=0x7fe7e4000930) at /usr/include/c++/4.8.2/functional:1720
  #9  0x000000000047372e in std::thread::_Impl&lt;std::_Bind_simple&lt;std::_Mem_fn&lt;void (WebManager::WebProcessor::*)(void*, char*)&gt; (WebManager::WebProcessor*, int*, char*)&gt; &gt;::_M_run() (this=0x7fe7e4000918)
      at /usr/include/c++/4.8.2/thread:115
  #10 0x00007fe7f4659070 in ?? () from /lib64/libstdc++.so.6
  #11 0x00007fe7f3aaae25 in start_thread () from /lib64/libpthread.so.0
  #12 0x00007fe7f3dbdbad in clone () from /lib64/libc.so.6
  </code></pre>
  
  <p>I've stepped through in GDB watching the memory location for Curl to see if something unexpectedly rights/corrupts to it but it doesn't look like there's any issues. </p>