feisky

云计算、虚拟化与Linux技术笔记
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

libcurl的段错误

Posted on 2012-10-08 09:31  feisky  阅读(2147)  评论(0编辑  收藏  举报
前不久在使用libcurl写多线程下载时候,出现莫名其妙的段错误。
问题出现在使用libcurl开多线程从任务队列下载文件后,因为下载队列空,所有下载线程锁在pthread_mutex_lock。这时,程序空闲几秒后会因为出现Segmentation fault退出。反复看我的代码也没看出什么问题来,最后竟然在讲libcurl基础的地方找到了答案,真惭愧,基础很重要啊!
原来libcurl在configure默认配置编译的情况下,它是使用alarm+siglongjmp实现域名解析超时。当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。libcurl将会发信号打断这个wait从而导致程序退出。so~,坑爹啊!给条警告能死啊?

好吧,谁让我一开始没仔仔细细阅读文档呢。一个解决方式是禁用掉这种超时,如果懒得整c-ares的话把这个选项设置成1就好了,curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L)。但是这样域名解析就没了超时机制。另一种解决方式是文档建议的“Consider building libcurl with c-ares support to enable asynchronous DNS lookups, which enables nice timeouts for name resolves without signals.”
CURLOPT_NOSIGNAL的说明如下:
CURLOPT_NOSIGNAL
Pass a long. If it is 1, libcurl will not use any functions that install signal handlers or any functions that cause signals to be sent to the process. This option is mainly here to allow multi-threaded unix applications to still set/use all timeout options etc, without risking getting signals. (Added in 7.10)
If this option is set and libcurl has been built with the standard name resolver, timeouts will not occur while the name resolve takes place. Consider building libcurl with c-ares support to enable asynchronous DNS lookups, which enables nice timeouts for name resolves without signals.
Setting CURLOPT_NOSIGNAL to 1 makes libcurl NOT ask the system to ignore SIGPIPE signals, which otherwise are sent by the system when trying to send data to a socket which is closed in the other end. libcurl makes an effort to never cause such SIGPIPEs to trigger, but some operating systems have no way to avoid them and even on those that have there are some corner cases when they may still happen, contrary to our desire. In addition, using CURLAUTH_NTLM_WB authentication could cause a SIGCHLD signal to be raised.
无觅相关文章插件,快速提升流量