c++ - libcurl curl_easy_perform 崩溃(段错误)c++

标签 c++ curl crash libcurl

对不起我的英语不好。 我正在尝试运行以下代码,但是当进度运行大约一天或几个小时时它会崩溃,所以这次崩溃是偶然出现的。 顺便说一句,SecMonitor_Curl 是一个单一的类,因此 curl_global_init() 只运行一次全局。 我无法解决这个问题,所以我不知道我的程序有什么问题。请帮我。谢谢!

   SecMonitor_Curl::SecMonitor_Curl()
{
    curl_global_init(CURL_GLOBAL_ALL);
}

SecMonitor_Curl::~SecMonitor_Curl()
{
    curl_global_cleanup();
}


static size_t write_to_string(void *ptr, size_t size, size_t nmemb, void *stream) {
    ((std::string*)stream)->append((char*)ptr, 0, size*nmemb);
    return size * nmemb;
}


int SecMonitor_Curl::http_get(const std::string url, const std::string method, const std::map<std::string, std::string>& params, std::string post_data, std::string& response)
{
    int ret = 0;
    CURLcode res;
    curl_ = curl_easy_init();
    if (curl_ == NULL)
    {
        return -1;
    }
    if(curl_)
    {
        url_t = "www.google.com";
        method = "POST";
        post_body="{"test":"test"}";

        res = curl_easy_setopt(curl_, CURLOPT_URL, url_t.c_str());

        if (method == "POST" || method == "PUT" || method == "DELETE")
        {
            curl_easy_setopt(curl_, CURLOPT_CUSTOMREQUEST, method.c_str());
            curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, post_body.c_str());
            curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, post_body.size());
        }

        res = curl_easy_setopt(curl_, CURLOPT_FOLLOWLOCATION, 1L);
        res = curl_easy_setopt(curl_, CURLOPT_NOSIGNAL, 1L); 
        res = curl_easy_setopt(curl_, CURLOPT_ACCEPT_ENCODING, "deflate");
        std::string out;
        res = curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, write_to_string);
        res = curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &out);

        //printf("curl_version : %s ",curl_version());
        res = curl_easy_perform(curl_);
        /* Check for errors */
        if (res != CURLE_OK) {
            srlog_error("SecMonitor_Curl | curl_easy_perform() failed: %s\n",
                    curl_easy_strerror(res));
            ret = -1;
        }
        response = out;
    }
    else
    {
        ret = -1;
    }
    curl_easy_cleanup(curl_);

    return ret;
}

这是转储文件:

Program terminated with signal 11, Segmentation fault.
#0  _IO_fwrite (buf=0x7f16a31dba70, size=2, count=1, fp=0x0) at iofwrite.c:43
43  iofwrite.c: No such file or directory.
    in iofwrite.c    
(gdb) bt
#0  _IO_fwrite (buf=0x7f16a31dba70, size=2, count=1, fp=0x0) at iofwrite.c:43
#1  0x00007f16a31aef93 in ?? () from /usr/lib64/libcurl.so.4
#2  0x00007f16a31af0c0 in Curl_debug () from /usr/lib64/libcurl.so.4
#3  0x00007f16a31afd69 in Curl_infof () from /usr/lib64/libcurl.so.4
#4  0x00007f16a31b55f4 in Curl_protocol_connect () from /usr/lib64/libcurl.so.4
#5  0x00007f16a31bbb0c in Curl_connect () from /usr/lib64/libcurl.so.4
#6  0x00007f16a31c3a90 in Curl_perform () from /usr/lib64/libcurl.so.4
#7  0x0000000000437a10 in SecMonitor_Curl::http_get (this=0x11e2db8, url=
    "http://dip.alibaba-inc.com/api/v2/services/schema/mock/61919?spm=a312q.7764190.0.0.40e80cf75fUogt", method="POST", params=std::map with 5 elements = {...}, post_data="", response="")
    at /home/albert.yb/secMonitorAgent/secMonitor/monitor/server/SecMonitor/SecMonitor_Curl.cpp:131
#8  0x0000000000435ab0 in SecMonitor_Cmd::run_cmd (this=0x11eeef8, cmd_name="update")

SecMonitor_Curl.cpp:131 :表示 curl_easy_perform()。

谢谢

最佳答案

我收集了3个write_to_string回调函数: 第一:

static size_t write_to_string(void *ptr, size_t size, size_t nmemb, void *stream) {
    ((std::string*)stream)->append((const char*)ptr, size*nmemb);
    return size * nmemb;
}

第二个:

static size_t write_to_string(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;
}

第三:

   struct MemoryStruct {
      char *memory;
      size_t size;
    };

    static size_t
    write_to_string(void *contents, size_t size, size_t nmemb, void *userp)
    {
      size_t realsize = size * nmemb;
      struct MemoryStruct *mem = (struct MemoryStruct *)userp;

      mem->memory = realloc(mem->memory, mem->size + realsize + 1);
      if(mem->memory == NULL) {
        /* out of memory! */
        printf("not enough memory (realloc returned NULL)\n");
        return 0;
      }

      memcpy(&(mem->memory[mem->size]), contents, realsize);
      mem->size += realsize;
      mem->memory[mem->size] = 0;

      return realsize;
    }

这些回调方法可以处理将 curl 响应输出到 String 的事情。但是这里没有这个问题,都是crash,因为“crul_”是这个类的成员变量。当“http_get”函数被多线程引用时,一定会崩溃。

关于c++ - libcurl curl_easy_perform 崩溃(段错误)c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45097847/

相关文章:

c++ - 如何在C++中实现动态元素容器

在机器 1 上编译的 C++ 代码无法在机器 2 上运行,因为 "GLIBCXX_3.4.15 not found"

javascript - cookie是由javascript生成的吗?

c++ - 如何使用 QWhatsThis 在 Qt 中启用动态 whatsthis-string?

c++使用冒泡排序自定义排序 vector

PHP file_get_contents 很慢并返回 500 Internal Server Error

python - Bottle POST 或 PUT 请求看不到多个参数

php - Yii 1.14 通知未定义偏移 : 0 in CUrlManager. php

javascript - 在没有 length 属性的变量上使用 .length 会导致崩溃

ios - iOS上的应用程序内购买导致奇怪的崩溃