簡體   English   中英

libcurl-“ curl_easy_cleanup()”導致malloc錯誤(C ++)

[英]libcurl - “curl_easy_cleanup()” is causing malloc error (C++)

運行我的代碼時(下面粘貼了相關的部分),我會定期收到以下錯誤:

程序(34010,0x70000e58b000)malloc:***對象0x7fc43d93fcf0的錯誤:未分配釋放的指針在malloc_error_break中設置了一個斷點來調試信號:SIGABRT(信號SIGABRT)

我在Macbook(OS-10.13)上運行多線程C ++代碼,其中不同的線程同時使用有問題的代碼。 據我所知,libcurl確實是線程安全的,只要我在兩個不同的線程中不使用相同的“ curl句柄”(我理解為“ CURL”的實例,又稱為“ CURL * curl = curl_easy_init();”)即可。與此同時。 就我而言,由於每個線程分別調用該函數並初始化CURL對象的新實例,所以我應該是“安全的”,對嗎? 希望我遺漏了一些明顯的東西,導致我(在這種情況下為lib curl)嘗試釋放已經釋放的內存。 如果還有其他我應該包括的信息(下),請隨時告訴我。

段故障的功能是

字符串http_lib :: make_get_request(字符串url)

在讀取的行上

curl_easy_cleanup(curl);

有時(不經常)在讀取的行上

res = curl_easy_perform(curl);

以下是我認為是代碼相關部分的內容:

size_t http_lib::CurlWrite_CallbackFunc_StdString(void *contents, size_t size, size_t nmemb, std::string *s)
{
    size_t newLength = size*nmemb;
    size_t oldLength = s->size();
    try
    {
        s->resize(oldLength + newLength);
    }
    catch(std::bad_alloc &e)
    {
        //handle memory problem
        return 0;
    }

    std::copy((char*)contents,(char*)contents+newLength,s->begin()+oldLength);
    return size*nmemb;
}

string http_lib::make_post_request(string url, vector<string> headers, string post_params) {
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    string s;
    if(curl)
    {
        struct curl_slist *chunk = NULL;

        for(int i=0; i<headers.size(); i++){
            /* Add a custom header */
            chunk = curl_slist_append(chunk, headers[i].c_str());
        }

        /* set our custom set of headers */
        res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_params.c_str());
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //only for https
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //only for https
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        if(networking_debug){
            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //verbose output
        }

        /* Perform the request, res will get the return code */
        res = curl_easy_perform(curl);

        /* Check for errors */
        if(res != CURLE_OK)
        {
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
        }

        /* always cleanup */
        curl_easy_cleanup(curl);
    }

    // Debug output
    if (networking_debug){
        cout<<"Response: " << s <<endl;
    }

    return s;
}

string http_lib::make_get_request(string url) {
    //SslCurlWrapper sslObject;
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();
    string s;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        //tell libcurl to follow redirection
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //only for https
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); //only for https
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWrite_CallbackFunc_StdString);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        if(networking_debug){
            curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //verbose output
        }

        /* Perform the request, res will get the return code */
        res = curl_easy_perform(curl);
        /* Check for errors */
        if (res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

        /* always cleanup */
        curl_easy_cleanup(curl);
    }

    if (networking_debug){
        cout << "Response: " << s << endl;
    }

    return s;
}

在main()中,我有

int main(int argc, char *argv[]){
    // Initialize http_lib (curl)
    curl_global_init(CURL_GLOBAL_DEFAULT);

    ... spin up 10 or so threads that make get/post requests to https site (some requests utilize the make_post_request() function and others utilize make_get_requet() function). 
}

除了“ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include”的CURL_ROOT_DIR之外,CMAKE似乎/不想使用其他任何東西。用於libcurl(又名curl)。

因此,它使用的是mac(和/或Xcode)隨附的curl lib。 我還沒有想通了,是什么版本,但我可以說, 使用它,而是使用curl版本7.57是什么固定我的問題。

我使用“釀造”包裝管理器

brew install curl

這樣就創建了/usr/local/Cellar/curl/7.57.0目錄,並將所有libs / includes放在其中。

然后我加了

 -I/usr/local/Cellar/curl/7.57.0/include -L/usr/local/Cellar/curl/7.57.0/lib

到我的CMAKE CMAKE_CXX_FLAGS。

TLDR; 解決方案是確保我使用的是最新版本的curl lib。 現在我沒問題了。

暫無
暫無

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

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