libcurl - “curl_easy_cleanup()”导致malloc错误(C ++)

时间:2017-11-29 03:16:23

标签: c++ curl segmentation-fault libcurl

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

  

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

我在Macbook(OS-10.13)上运行多线程C ++代码,其中不同的线程同时使用有问题的代码。据我所知,libcurl确实是线程安全的,只要我不在两个不同的线程中使用相同的“curl句柄”(我理解为“CURL”的实例,又称“CURL * curl = curl_easy_init();”)同时。在我的情况下,由于每个线程分别调用函数并初始化CURL对象的新实例,我应该是“安全的”,对吧?希望有一些显而易见的东西,我错过了导致我(或本例中的lib curl)尝试释放已经释放的内存。如果我应该包含更多信息(如下),请不要犹豫,让我知道。

seg fault的功能是

  

string http_lib :: make_get_request(string url)

在读取

的行上
  

curl_easy_cleanup(卷曲);

并且有时(不太经常)在读取

的行上
  

res = curl_easy_perform(curl);

以下是我认为我的代码的相关部分:

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
  if ([UIDevice currentDevice].systemVersion.floatValue < 11) {
    return;
  }
  if ([viewController isKindOfClass:NSClassFromString(@"PUPhotoPickerHostViewController")]) {
    weakify(viewController);
    [viewController.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
      if (obj.frame.size.width < 42 && FLOAT_EQUAL(obj.frame.size.height, [[UIScreen mainScreen] bounds].size.height)) {
        strongify(viewController);
        [viewController.view sendSubviewToBack:obj];
        *stop = YES;
      }
    }];
  }
}

在main()中我有

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;
}

1 个答案:

答案 0 :(得分:0)

CMAKE似乎不想使用“/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr”的CURL_ROOT_DIR以外的任何内容。 / include“for libcurl(aka curl)。

因此它使用了mac(和/或Xcode)附带的curl lib。我还没弄明白是什么版本,但是我可以说使用它而使用CURL版本7.57是修复我的问题。

我使用“brew”包管理器

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。现在我,没问题。

相关问题