代码之家  ›  专栏  ›  技术社区  ›  Xandrix

libcurl-“curl\u easy\u cleanup()”导致malloc错误(C++)

  •  0
  • Xandrix  · 技术社区  · 7 年前

    当运行我的代码(粘贴在下面的相关部分)时,我会定期出现以下错误:

    程序(34010,0x70000e58b000)malloc:**对象错误 0x7fc43d93fcf0:未为被释放的指针分配设置断点 在malloc\u error\u中断到调试信号:SIGABRT(信号SIGABRT)

    我正在Macbook(OS-10.13)上运行多线程C++代码,其中不同的线程同时使用所讨论的代码。据我所知,libcurl确实是线程安全的,只要我不使用相同的“curl句柄”(我理解为“curl”的一个实例,即“curl*curl=curl\u easy\u init();”)同时在两个不同的线程中。在我的例子中,由于每个线程分别调用函数并初始化CURL对象的新实例,所以我应该是“安全的”,对吗?希望我遗漏了一些明显的东西,导致我(在本例中是lib curl)尝试释放已经释放的内存。如果有任何更多我应该包括的信息(以下),请不要犹豫,让我知道。

    seg故障的功能是

    字符串http\u lib::make\u get\u请求(字符串url)

    在上面写着

    curl\u easy\u cleanup(curl);

    有时(不太经常)在读

    res=curl\u easy\u 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). 
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Xandrix    7 年前

    对于libcurl(也称为CURL),CMAKE似乎不想/不想使用“/应用程序/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include”的CURL\u ROOT\u DIR之外的任何东西。

    因此,它使用了mac(和/或Xcode)附带的curl库。我还不知道那是什么版本,但我可以这么说 使用它,而不是使用卷曲版本7.57是什么 固定的 我的问题。

    我使用“brew”包管理器

    brew install curl
    

    这样做会创建/usr/local/cillar/curl/7.57.0目录,并将所有lib/include放在其中。

    然后我补充说

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

    到我的CMAKE CMAKE\u CXX\u标志。

    太长,读不下去了解决方案是确保我使用的是最新版本的curl库。既然我是,没问题。