多线程中使用curl致coredump问题
coredump时的调用栈:
#0 0x081eff2c in addbyter ()
#1 0x081f05b8 in dprintf_formatf ()
#2 0x081f15cf in curl_mvsnprintf ()
#3 0x081f0079 in curl_msnprintf ()
#4 0x081ef55c in Curl_failf ()
#5 0x081fa1a3 in Curl_resolv_timeout ()
#6 0xeb8fbdd4 in ?? ()
#7 0x00000000 in ?? ()
coredump的原因是因为curl的DNS解析超时控制是使用SIGALARM实现的。
这样导致发现SIGALARM会出现多线程修改同一个全局变量,由此产生了COREDUMP。
问题发生的前提是设置了CURLOPT_TIMEOUT或CURLOPT_CONNECTTIMEOUT,并且值不为0。
解决办法:
1) 设置CURLOPT_NOSIGNAL的值为1
2) 使用c-ares(configure时指定参数--enable-ares)
lib/curl_setup.h(异步模式使用c-ares控制DNS解析超时):
只有当configure时指定了--enable-ares才会定义USE_ARES。
#ifdef USE_ARES
# define CURLRES_ASYNCH
# define CURLRES_ARES
/* now undef the stock libc functions just to avoid them being used */
# undef HAVE_GETADDRINFO
# undef HAVE_GETHOSTBYNAME
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
# define CURLRES_ASYNCH
# define CURLRES_THREADED
#else
# define CURLRES_SYNCH
#endif
lib/hostip.c(同步模式使用ALARM控制DNS解析超时):
只有定义了CURLRES_SYNCH,才可能定义USE_ALARM_TIMEOUT。
#if defined(CURLRES_SYNCH) && \
defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP)
/* alarm-based timeouts can only be used with all the dependencies satisfied */
#define USE_ALARM_TIMEOUT
#endif
相关源代码:
lib/asyn-ares.c:
Curl_resolver_getaddrinfo
lib/hostasyn.c(基于c-ares的异步版本Curl_getaddrinfo):
Curl_resolver_getaddrinfo <-- Curl_getaddrinfo
从缓存中找(hostip.c):
fetch_addr <-- Curl_resolv
hostip.c:
Curl_ipv4_resolve_r <-- Curl_getaddrinfo <-- Curl_resolv
hostip.c:
curl_jmpenv <-- sigaction(SIGALRM, alarmfunc)/sigsetjmp(curl_jmpenv) <- Curl_resolv_timeout <-
url.c:
Curl_resolv_timeout(hostname) <-- resolve_server <-- create_conn <-- Curl_connect
multi.c:
Curl_connect <--
transfer.c
Curl_connect <-- Curl_reconnect_request
url.c:
Curl_reconnect_request <-- Curl_do
multi.c:
Curl_do <-- multi_runsingle <-- curl_multi_perform <-- multi_socket <-- curl_multi_socket
多线程中使用curl致coredump问题的更多相关文章
- PHP中使用CURL实现GET和POST请求数据
PHP中使用CURL实现GET和POST请求 一.什么是CURL? cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.最爽的是,PHP也支持 ...
- php 中使用cURL发送get/post请求,上传图片,批处理
cURL是利用url语法规定传输文件和数据的工具.php中有curl拓展,一般用来实现网络抓取,模拟发送get post请求,文件上传. 在php中建立curl的基本步骤如下: 1 初始化 ...
- PHP中使用CURL请求页面,使用fiddler进行抓包
在PHP中使用CURL访问页面: <?php $ch = curl_init('http://www.baidu.com'); curl_setopt($ch, CURLOPT_RETURNTR ...
- PHP中使用cURL实现Get和Post请求的方法
1.cURL介绍 cURL 是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP.FTP.TELNET等.最爽的是,PHP也支持 cURL 库.本文将介绍 cURL 的一些高级特 ...
- c#初学-多线程中lock用法的经典实例
本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被 ...
- iOS多线程中,队列和执行的排列组合结果分析
本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...
- php中的curl使用入门教程和常见用法实例
摘要: [目录] php中的curl使用入门教程和常见用法实例 一.curl的优势 二.curl的简单使用步骤 三.错误处理 四.获取curl请求的具体信息 五.使用curl发送post请求 六.文件 ...
- PHP中的CURL函数库
PHP中的CURL函数库(Client URL Library Function) curl_close — 关闭一个curl会话curl_copy_handle — 拷贝一个curl连接资源的所有内 ...
- 解决DataGridView在多线程中无法显示滚动条的问题
在多线程中对DataGridView指定 DataSource 来填充数据,更新数据的时候,会导致DataGridView出现假死,显示错误或者滚动条无法显示的问题,在保证了DataGridView的 ...
随机推荐
- 拓扑排序获取所有可能序列JAVA实现
在看算法基础这本书,看到有向无环图,其中介绍到了拓扑排序,讲到了获取拓扑序列的方法,结合自己的理解,用JAVA代码实现了获取所有可能序列,水平有限,效率什么的就没有考虑,下面贴上代码: package ...
- Hibernate Annotation 设置字段的默认值
很简单,不过有点莫名其妙的意思 @Column(name="powerLoad",columnDefinition="bit(1) default 1 ") p ...
- No matter how hard it is or no matter how bad it gets, I am going to make it!
No matter how hard it is or no matter how bad it gets, I am going to make it! He always had a yearni ...
- 如何判断int类型相等
int a=10: int b=10: a==b 通过==判断两个int值是否相等. if(a==b){ 相等 }else{ 不相等 }
- redis lua 用来传输日志
2.8 Lua Script Redis2.6内置的Lua Script支持,可以在Redis的Server端一次过运行大量逻辑,就像存储过程一样,避免了海量中间数据在网路上的传输. Lua自称是在S ...
- express.Router
[express.Router] 1.可使用 express.Router 类创建模块化.可挂载的路由句柄.Router 实例是一个完整的中间件和路由系统,因此常称其为一个 “mini-app”. 下 ...
- selenium常用的断言
断言: 验证应用程序的状态是否同期望的一致,常见的断言包括验证页面内容,如标题是否与预期一致,当前的位置是否正确等等 断言常被用的4种模式+5种手段:Assert 断言失败的时候,该测试终止 veri ...
- Jmeter分布式
Jmeter运行时十分耗CPU和内存,在实际应用中有时一台机器不能满足测试要求,这时就需要利用多台机器来进行分布式. Jmeter分布式的测试框架:框架中所有的测试脚本都要从测试主机传送到测试从机 ...
- suse安装gcc,升级到4.8.5
前面这些是挂载iso,如果iso可以使用,就不需要下面几步. cd /etc/zypp/repos.d mkdir iso chmod -R 777 iso mount -o loop /media/ ...
- Segments(叉积)
Segments http://poj.org/problem?id=3304 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: ...