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_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
相關源代碼:
lib/asyn-ares.c:
Curl_resolver_getaddrinfo
lib/hostasyn.c(基于c-ares的異步版本Curl_getaddrinfo):
從緩存中找(hostip.c):
fetch_addr
hostip.c:
Curl_ipv4_resolve_r
curl_jmpenv
url.c:
Curl_resolv_timeout(hostname)
multi.c:
Curl_connect
transfer.c
Curl_reconnect_request
Curl_do