I have found a very random dangling pointer problem: this occurs in FTP when verbose mode is enabled. The conn->ip_addr set at the start of the request is not valid anymore if the DNS cache entry has been destroyed by the resolver at EPSV time. I use the hostip6 resolver (no ares, no threaded). Unfortunately, it is not easy to reproduce. But here is the verbose+valgrind output (real IP address replaced for confidentiality). ------------- > EPSV * FTP 0x4fcc1c8 (line 1378) state change from STOP to PASV * Connect data stream passively * ftp_perform ends with SECONDARY: 0 * STATE: DO => DOING handle 0x4fb90e8; line 1291 (connection #0) < 229 Entering Extended Passive Mode (|||30005|). * Hostname in DNS cache was stale, zapped * Trying 123.145.167.189... ==5828== Invalid read of size 4 ==5828== at 0x4C1AC1D: Curl_printable_address (hostip.c:175) ==5828== by 0x4C30B1C: ftp_pasv_verbose (ftp.c:3558) ==5828== by 0x4C2DE76: ftp_state_pasv_resp (ftp.c:2091) ==5828== by 0x4C2FE92: ftp_statemach_act (ftp.c:3106) ==5828== by 0x4C6B661: Curl_pp_statemach (pingpong.c:131) ==5828== by 0x4C2FF38: ftp_multi_statemach (ftp.c:3140) ==5828== by 0x4C328DE: ftp_doing (ftp.c:4447) ==5828== by 0x4C3C877: Curl_protocol_doing (url.c:3525) ==5828== by 0x4C57299: multi_runsingle (multi.c:1373) ==5828== by 0x4C57FC8: curl_multi_perform (multi.c:1790) ==5828== by 0x4C4CDD9: easy_transfer (easy.c:715) ==5828== by 0x4C4CF77: easy_perform (easy.c:803) ==5828== Address 0x4fd33dc is 12 bytes inside a block of size 64 free'd ==5828== at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==5828== by 0x4C51090: curl_dofree (memdebug.c:334) ==5828== by 0x4C62411: Curl_freeaddrinfo (curl_addrinfo.c:87) ==5828== by 0x4C1B7B1: freednsentry (hostip.c:739) ==5828== by 0x4C54537: hash_element_dtor (hash.c:40) ==5828== by 0x4C541F2: Curl_llist_remove (llist.c:132) ==5828== by 0x4C54A7D: Curl_hash_delete (hash.c:194) ==5828== by 0x4C1AF5E: fetch_addr (hostip.c:319) ==5828== by 0x4C1B20A: Curl_resolv (hostip.c:458) ==5828== by 0x4C2DD94: ftp_state_pasv_resp (ftp.c:2057) ==5828== by 0x4C2FE92: ftp_statemach_act (ftp.c:3106) ==5828== by 0x4C6B661: Curl_pp_statemach (pingpong.c:131) ----------- More similar valgind events follow.
How would you fix it? - live with the dangling pointer and have a simpler verbose output. - copy the addrinfo to conn->ip_addr rather than pointing to the DNS cache data. - Keep the DNS cache entry with "inuse" bumped. - Something else. To try to make it occur: curl_easy_setopt(h, CURLOPT_DNS_CACHE_TIMEOUT, 1L); curl_easy_setopt(h, CURLOPT_VERBOSE, 1L); curl_easy_setopt(h, CURLOPT_URL, "ftp://yourtestserver/"); curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, nooutput); for (;;) { res = curl_easy_perform(h); if (res == CURLE_OK) sleep(2); else break; } Note: I initially discovered it on the OS/400 since after many requests, conn->ip_addr->ai_addr is NULL and thus segfaults. Patrick ------------------------------------------------------------------- List admin: http://cool.haxx.se/list/listinfo/curl-library Etiquette: http://curl.haxx.se/mail/etiquette.html
