libcurl中使用curl_easy_getinfo 产生段错误分析
浏览:4117次 出处信息
最近再写一个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;
输出:
[hailong.xhl@v101080140 test]$ ./test p value 202 b value b 段错误
看来,宽松意为着需要更加严谨。没有条条框框的约束,得做好自我约束。
建议继续学习:
- libcurl的使用总结(二) (阅读:13858)
- iPhone下的libcurl with SSL for iOS (阅读:5005)
- libcurl的使用总结(一) (阅读:3275)
- 关于libcurl不发包的bug定位 (阅读:3043)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:深入分析Volatile的实现原理
文章信息
- 作者:信海龙 来源: 博学无忧
- 标签: curl_easy_getinf libcurl
- 发布时间:2014-11-06 23:57:54
近3天十大热文
- [65] Oracle MTS模式下 进程地址与会话信
- [65] Go Reflect 性能
- [64] 如何拿下简短的域名
- [59] android 开发入门
- [59] IOS安全–浅谈关于IOS加固的几种方法
- [58] 图书馆的世界纪录
- [58] 【社会化设计】自我(self)部分――欢迎区
- [53] 视觉调整-设计师 vs. 逻辑
- [47] 界面设计速成
- [46] 读书笔记-壹百度:百度十年千倍的29条法则