Linux | c&cpp | Email | github | QQ群:425043908 关注本站

itarticle.cc

您现在的位置是:网站首页 -> 代码相关 文章内容

libcurl中使用curl_easy_getinfo 产生段错误分析-itarticl.cc-IT技术类文章记录&分享

发布时间: 9年前代码相关 120人已围观返回

最近再写一个hsf的代理程序。需要使用libcurl与后端的nginx通信。程序编写过程中遇到一个蹊跷的问题。

调用 code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rsp_code); 后会报段错误。

示例代码如下:

static int http_proxy(std::string domain, std::string path, std::string params, std::string &rsp_cont, std::string host = ""){

string url;

int rsp_code; //此处设置为int类型 会有段错误。如果long类型没问题。

char str_rsp_code[5] = {'\0'};

CURLcode code;

CURL* curl;

curl_slist *headers = NULL;

curl = curl_easy_init();


curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

curl_easy_setopt(curl, CURLOPT_USERAGENT, "hsfproxy");

curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_write);

curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&rsp_cont);

curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);

curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);

curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);

code = curl_easy_perform(curl);

code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rsp_code);

curl_easy_cleanup(curl);

sprintf(str_rsp_code,"%d",rsp_code);

log("curl: http code["+ (std::string)str_rsp_code +"] url[" + (std::string)url + "] domain["+ domain +"]", __FILE__, __LINE__, __FUNCTION__, LOG_VERBOSE);

return 1;

}

问题:

int rsp_code;

code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rsp_code);

当rsp_code设置为int类型 会有段错误。如果long类型没问题。

分析:

下载了libcurl的代码,查找原因。

原来curl_easy_getinfo的实现使用了可变参数。即,在编译时不进行参数个数和参数类型检测。这样,在使用这个函数时,无论你传入的类型是int还是long,都不会报错。虽然,它要求的是long类型。不过,在赋值的时候,他可是按long类型赋值的。这样就导致栈被破坏了。当然就报段错误了。

相关代码如下:

#undef curl_easy_getinfo

CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)

{

va_list arg;

void *paramp;

CURLcode ret;

struct SessionHandle *data = (struct SessionHandle *)curl;


va_start(arg, info);

paramp = va_arg(arg, void *);


ret = Curl_getinfo(data, info, paramp);


va_end(arg);

return ret;

}

验证:

编写了示例代码,验证了假设。注意此代码在32位操作系统上不会报错,在64位操作系统上会报段错误。注意只有在int和long类型长度不一致时才会出现段错误。如在64位操作系统。

#include <iostream>

#include <string>

#include <cstdarg>


using namespace std;


void f(char chr, ...){

long value = 202;

long *paramp;

va_list arg_ptr;

va_start(arg_ptr, chr);

paramp = va_arg(arg_ptr, long *);

va_end(arg_ptr);

*paramp = value;

}

int main(){

string a;

int p=0;

string b;

a = "a";

b = "b";

f('a',&p);

cout << "p value " << p << endl;

cout << "a value " << a << endl;

cout << "b value " << b << endl;

输出:

[root@v101080140 test]$ ./test

p value 202

b value b

段错误

看来,宽松意为着需要更加严谨。没有条条框框的约束,得做好自我约束。

发布时间: 9年前代码相关120人已围观返回回到顶端

很赞哦! (1)

文章评论

  • 请先说点什么
    热门评论
    119人参与,0条评论

站点信息

  • 建站时间:2016-04-01
  • 文章统计:728条
  • 文章评论:82条
  • QQ群二维码:扫描二维码,互相交流