簡體   English   中英

curl_easy_perform在Linux上的分段錯誤

[英]curl_easy_perform segmentation fault on Linux

我正在使用使用curl來響應HTTP GET請求的C ++應用程序。 它在Windows上運行良好,但在Linux(CentOS 7)上,使用curl_easy_cleanup時出現分段錯誤。

下面是我的代碼

CURL* curl = NULL;
    curl = curl_easy_init();

    if (curl == NULL)
    {

        this->getBitsLibrary()->writeToLog("Failed to init curl");
        this->getBitsLibrary()->setAlarm("CrashInfo", Alarms::AlarmLevel::Critical, "Failed to init curl for IP lookup");
        return;
    }

    stringstream urlstream;
    string iplookupURL;
    //curlResponse = "";
    urlstream << StaticSettings::IP_Lookup::ipLookupURL << "/" << clientIP << "?access_key="<<StaticSettings::IP_Lookup::api_key;
    iplookupURL = urlstream.str();
    logstream << "Using URL " << iplookupURL << " for IP lookup";
    this->getBitsLibrary()->writeToLog(logstream.str(), "CrashInfo", "performIPLookup");
    logstream.clear();
    logstream.str(string());
    //string response = "";
    this->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, &curlStaticCallback);



    CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK)
    {
        logstream << "Failed to perform IP lookup using curl";
        this->getBitsLibrary()->writeToLog(logstream.str(), "CrashInfo", "performIPLookup");
        this->getBitsLibrary()->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, &httpResponseCode);
    if (httpResponseCode == 200)
    {

        if (!this->curlResponse->empty())
        {
            this->getBitsLibrary()->writeToLog("Processing response for IP lookup");
            rapidjson::Document jsonObject;
            jsonObject.Parse(this->curlResponse->c_str());

            const rapidjson::Value& countryValue = jsonObject["country_name"];
            if (!countryValue.IsNull())
            {
                string country = string(jsonObject["country_name"].GetString());
                this->setCountry(!country.empty() ? country : "N/A");
            }
            else
            {
                this->setCountry("N/A");
            }

            const rapidjson::Value& cityValue = jsonObject["city"];
            if (!cityValue.IsNull())
            {
                string city = string(jsonObject["city"].GetString());
                this->setCity(!city.empty() ? city : "N/A");
            }
            else
            {
                this->setCity("N/A");
            }

            this->getBitsLibrary()->writeToLog("IPLookup performed successfully", "CrashInfo", "performIPLookup");
        }
delete this->curlResponse;
    this->curlResponse = NULL;
    curl_easy_cleanup(curl);

由於curl是C庫,因此我創建了一個靜態函數(在C ++類之外),如下所示:

size_t curlStaticCallback(void *contents, size_t size, size_t nmemb, void * userp)
{
    CrashInfo *crashInfo = (CrashInfo*)userp;
    crashInfo->curlResponseWriteCallback(contents, size, nmemb, userp);
    return size * nmemb;
}

上面的靜態函數由curl中的WRITEFUNCTION調用。 我得到了類對象,然后調用C ++函數,如下所示:

size_t CrashInfo::curlResponseWriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
    curlResponse->append((char*)contents, size * nmemb);
    return size * nmemb;
}

如上所述,這在Windows上可以正常運行,但是在Linux上,可以在獲得預期響應的URL上正常運行,但是當curl_easy_cleanup被調用時,我得到了包含以下堆棧的分段錯誤:

#0  0x00007fe7f45ff2ad in ?? () from /lib64/libstdc++.so.6
#1  0x00007fe7f4661c03 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~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<void (WebManager::WebProcessor::*)(void*, char*)>::operator()<int*, char*, void>(WebManager::WebProcessor*, int*&&, char*&&) const (this=0x7fe7e4000948, __object=0x7fe7ed841a60)
    at /usr/include/c++/4.8.2/functional:601
#7  0x00000000004739fd in std::_Bind_simple<std::_Mem_fn<void (WebManager::WebProcessor::*)(void*, char*)> (WebManager::WebProcessor*, int*, char*)>::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) (this=0x7fe7e4000930)
    at /usr/include/c++/4.8.2/functional:1732
#8  0x00000000004737fd in std::_Bind_simple<std::_Mem_fn<void (WebManager::WebProcessor::*)(void*, char*)> (WebManager::WebProcessor*, int*, char*)>::operator()() (this=0x7fe7e4000930) at /usr/include/c++/4.8.2/functional:1720
#9  0x000000000047372e in std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (WebManager::WebProcessor::*)(void*, char*)> (WebManager::WebProcessor*, int*, char*)> >::_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

我已經在GDB中逐步檢查了Curl的內存位置,以查看是否有意外的權限/損壞了它,但看起來沒有任何問題。

我已經弄清楚了問題,這很奇怪。 正如邁克爾·杜貝茲(Michael Doubez)在評論中說的那樣,它並不是直接卷曲的。 我以為是卷曲的,因為堆棧軌道中的第二行指向curl_easy_cleanup,然后最上面的一行是字符串析構函數,因此認為它是卷曲的。

我在curl_easy_cleanup之后放了一條日志行,它成功記錄了日志,然后崩潰了。 curl_easy_cleanup是方法中的最后一次調用,它是函數完成崩潰時發生的。

我最終注釋掉了整個功能,然后慢慢地重新添加了它的大塊,以明確導致它崩潰的那一點。

最后是curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpResponseCode); 當函數需要一個指向long的指針時,我正在傳遞一個指向int的指針。

我糾正了上面的問題,現在一切都按預期進行了,不能完全確定為什么雖然這樣做沒有做到以下幾點:1,引發編譯器警告,即我傳遞了錯誤的類型; 2,為什么堆棧跟蹤顯示了被破壞的字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM