Edit report at http://bugs.php.net/bug.php?id=52284&edit=1
ID: 52284 Comment by: profy dot net at gmail dot com Reported by: ahar...@php.net Summary: Reproducible crash using curl_multi functions with FTP Status: Open Type: Bug Package: cURL related Operating System: Ubuntu 10.04 (and others) PHP Version: 5.3SVN-2010-07-08 (SVN) New Comment: I see this bug too. It happens to me when using curl_multi_* with 2 or more ftp urls inside. Both under windows (XP SP3) and Ubuntu (8.10 and 9.10) PHP 5.2.13 Previous Comments: ------------------------------------------------------------------------ [2010-07-08 10:00:56] ahar...@php.net Description: ------------ The attached script segfaults on most executions. This occurs both on Linux and Windows and is reasonably, but not completely, reliable. The valgrind output attached below kind of suggests memory corruption somewhere, but I'm hoping someone with more knowledge of curl can look into this, since I don't have the time at present for a detailed investigation. Note that I'm not the original reporter of this bug (dumont reported it on ##php), but since I've generated the backtraces and have it crashing reliably, he/she has asked me to post the bug report. Test script: --------------- <?php set_time_limit(0); $urls = array('/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt');//, '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt', '/test123.txt'); $threads = 5; $timeout = 300; $mcurl = curl_multi_init(); $threadsRunning = 0; $urls_id = 0; for(;;) { // Fill up the slots while ($threadsRunning < $threads && $urls_id < count($urls)) { echo 'Adding download link: '.$urls[$urls_id].'-URLID: '.$urls_id.'-URL: '.'ftp://test12345678:test12345...@www.ftpwt.com/'.$urls[$urls_id]."<br>\r\n"; flush(); $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_URL, 'ftp://test12345678:test12345...@www.ftpwt.com/'.$urls[$urls_id]); curl_multi_add_handle($mcurl, $ch); $urls_id++; $threadsRunning++; } // Check if done if($threadsRunning == 0 && $urls_id >= count($urls)) { echo 'NO MORE THREADS LEFT'; break; } // Let mcurl do it's thing curl_multi_select($mcurl); while(($mcRes = curl_multi_exec($mcurl, $mcActive)) == CURLM_CALL_MULTI_PERFORM) { usleep(10000); } if($mcRes != CURLM_OK) { echo '!!!NOT OK!!!'; break; } while($done = curl_multi_info_read($mcurl)) { $ch = $done['handle']; $done_url = curl_getinfo($ch);//CURLINFO_EFFECTIVE_URL $done_content = curl_multi_getcontent($ch); echo $done_content."<br>"; #if(curl_errno($ch) == 0) { # $count = (preg_match('#of about <b>([^>]+)</b>#i', $done_content, $g) ? $g[1] : 'many'); # echo "Link <a href='$done_url'>$done_url</a> found $count links.<br>\n"; # flush(); # } else { # echo "Link <a href='$done_url'>$done_url</a> failed: ".curl_error($ch)."<br>\n"; # flush(); # } echo 'removing curlmulti handle'; curl_multi_remove_handle($mcurl, $ch); echo 'REMOVED curlmulti handle'; curl_close($ch); $threadsRunning--; } } curl_multi_close($mcurl); echo 'Done.'; ?> Expected result: ---------------- Not a segfault. :) Actual result: -------------- (gdb) r curl.php Starting program: /usr/local/bin/php curl.php [Thread debugging using libthread_db enabled] Adding download link: /test123.txt-URLID: 0-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 1-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 2-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 3-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 4-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> 111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handleAdding download link: /test123.txt-URLID: 5-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 6-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 7-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> 111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handleNO MORE THREADS LEFT Program received signal SIGSEGV, Segmentation fault. 0x00000000005751dc in curl_write_header ( data=0x14d6bb8 "221-Goodbye. You uploaded 0 and downloaded 1 kbytes.\r\n221 Logout.\r\n), 45.85 Kbytes per second\r", size=1, nmemb=54, ctx=0x14824e0) at /home/aharvey/php/php/php-src/branches/PHP_5_3/ext/curl/interface.c:1119 1119 php_curl_write *t = ch->handlers->write_header; (gdb) bt #0 0x00000000005751dc in curl_write_header ( data=0x14d6bb8 "221-Goodbye. You uploaded 0 and downloaded 1 kbytes.\r\n221 Logout.\r\n), 45.85 Kbytes per second\r", size=1, nmemb=54, ctx=0x14824e0) at /home/aharvey/php/php/php-src/branches/PHP_5_3/ext/curl/interface.c:1119 #1 0x00007ffff5477c26 in Curl_client_write () from /usr/lib/libcurl.so.4 #2 0x00007ffff54785ad in ftp_readresp () from /usr/lib/libcurl.so.4 #3 0x00007ffff547b2ed in ftp_statemach_act () from /usr/lib/libcurl.so.4 #4 0x00007ffff547c64f in ftp_easy_statemach () from /usr/lib/libcurl.so.4 #5 0x00007ffff547c792 in ftp_disconnect () from /usr/lib/libcurl.so.4 #6 0x00007ffff547e9b2 in Curl_disconnect () from /usr/lib/libcurl.so.4 #7 0x00007ffff5494813 in curl_multi_cleanup () from /usr/lib/libcurl.so.4 #8 0x000000000057c243 in _php_curl_multi_close (rsrc=0x147b278) at /home/aharvey/php/php/php-src/branches/PHP_5_3/ext/curl/multi.c:327 #9 0x0000000000991217 in list_entry_destructor (ptr=0x147b278) at /home/aharvey/php/php/php-src/branches/PHP_5_3/Zend/zend_list.c:184 #10 0x000000000098e0a3 in zend_hash_del_key_or_index (ht=0x122a6d0, arKey=0x0, nKeyLength=0, h=4, flag=1) at /home/aharvey/php/php/php-src/branches/PHP_5_3/Zend/zend_hash.c:497 #11 0x0000000000990d2b in _zend_list_delete (id=4) at /home/aharvey/php/php/php-src/branches/PHP_5_3/Zend/zend_list.c:58 #12 0x000000000057c210 in zif_curl_multi_close (ht=1, return_value=0x14864c0, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0) at /home/aharvey/php/php/php-src/branches/PHP_5_3/ext/curl/multi.c:319 #13 0x00000000009b3d56 in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7e77090) at /home/aharvey/php/php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h:316 #14 0x00000000009b86db in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x7ffff7e77090) at /home/aharvey/php/php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h:1606 #15 0x00000000009b3109 in execute (op_array=0x1479480) at /home/aharvey/php/php/php-src/branches/PHP_5_3/Zend/zend_vm_execute.h:107 #16 0x000000000097dc6c in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/aharvey/php/php/php-src/branches/PHP_5_3/Zend/zend.c:1194 #17 0x00000000008fe388 in php_execute_script (primary_file=0x7fffffffe0b0) at /home/aharvey/php/php/php-src/branches/PHP_5_3/main/main.c:2260 #18 0x0000000000a6aaf1 in main (argc=2, argv=0x7fffffffe318) at /home/aharvey/php/php/php-src/branches/PHP_5_3/sapi/cli/php_cli.c:1192 Valgrind output: ahar...@aharvey-desktop:/tmp$ valgrind php curl.php ==12870== Memcheck, a memory error detector ==12870== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==12870== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==12870== Command: php curl.php ==12870== Adding download link: /test123.txt-URLID: 0-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 1-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 2-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 3-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 4-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> 111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handleAdding download link: /test123.txt-URLID: 5-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 6-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> Adding download link: /test123.txt-URLID: 7-URL: ftp://test12345678:test12345...@www.ftpwt.com//test123.txt<br> 111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle111<br>removing curlmulti handleREMOVED curlmulti handle<br>removing curlmulti handleREMOVED curlmulti handleNO MORE THREADS LEFT==12870== Invalid read of size 8 ==12870== at 0x5751DC: curl_write_header (interface.c:1119) ==12870== by 0x756DC25: Curl_client_write (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x756E5AC: ftp_readresp (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x75712EC: ftp_statemach_act (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x757264E: ftp_easy_statemach (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x7572791: ftp_disconnect (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x75749B1: Curl_disconnect (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x758A812: curl_multi_cleanup (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x57C242: _php_curl_multi_close (multi.c:327) ==12870== by 0x991216: list_entry_destructor (zend_list.c:184) ==12870== by 0x98E0A2: zend_hash_del_key_or_index (zend_hash.c:497) ==12870== by 0x990D2A: _zend_list_delete (zend_list.c:58) ==12870== Address 0x5a5a5a5a5a5a5a62 is not stack'd, malloc'd or (recently) free'd ==12870== ==12870== ==12870== Process terminating with default action of signal 11 (SIGSEGV) ==12870== General Protection Fault ==12870== at 0x5751DC: curl_write_header (interface.c:1119) ==12870== by 0x756DC25: Curl_client_write (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x756E5AC: ftp_readresp (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x75712EC: ftp_statemach_act (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x757264E: ftp_easy_statemach (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x7572791: ftp_disconnect (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x75749B1: Curl_disconnect (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x758A812: curl_multi_cleanup (in /usr/lib/libcurl.so.4.1.1) ==12870== by 0x57C242: _php_curl_multi_close (multi.c:327) ==12870== by 0x991216: list_entry_destructor (zend_list.c:184) ==12870== by 0x98E0A2: zend_hash_del_key_or_index (zend_hash.c:497) ==12870== by 0x990D2A: _zend_list_delete (zend_list.c:58) ==12870== ==12870== HEAP SUMMARY: ==12870== in use at exit: 3,263,498 bytes in 20,184 blocks ==12870== total heap usage: 22,471 allocs, 2,287 frees, 3,875,285 bytes allocated ==12870== ==12870== LEAK SUMMARY: ==12870== definitely lost: 0 bytes in 0 blocks ==12870== indirectly lost: 0 bytes in 0 blocks ==12870== possibly lost: 298,550 bytes in 280 blocks ==12870== still reachable: 2,964,948 bytes in 19,904 blocks ==12870== suppressed: 0 bytes in 0 blocks ==12870== Rerun with --leak-check=full to see details of leaked memory ==12870== ==12870== For counts of detected and suppressed errors, rerun with: -v ==12870== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 14 from 6) Segmentation fault ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=52284&edit=1