ID: 46756 Updated by: [EMAIL PROTECTED] Reported By: kyle at ifixit dot com Status: Verified Bug Type: cURL related Operating System: * PHP Version: 5CVS, 6CVS (2008-12-08) New Comment:
I checked the origin of the crash, and it seems that libcurl does NOT behave good if you duplicate a handle while it's part of a curl_multi. Calling curl_multi_remove_handle($mh, $conn[$i]); before $conn2[$i] = curl_copy_handle($conn[$i]); fixes the issue. Checking curl's documentation, I found it to be quite picky about processing order. I believe this is either a bug in libcurl, or a "feature". libcurl's manpages are not providing exact informations about calling curl_easy_duphandle() on a curl handle part of a curl_multi. I'm going to investigate this more and either fix this bug (by providing a patch) or mark it as bogus (if this is a curl feature). Previous Comments: ------------------------------------------------------------------------ [2008-12-08 11:33:38] [EMAIL PROTECTED] Verified with latest CVS + Curl 7.18.2 ------------------------------------------------------------------------ [2008-12-07 16:45:51] kyle at ifixit dot com Reproducible using libcurl/7.19.2 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5 on kernel 2.6.18-53.1.14.el5. This is not a new bug-- also reproducible with PHP 5.2.6 and an older version of libcurl. ------------------------------------------------------------------------ [2008-12-07 09:54:13] [EMAIL PROTECTED] I cannot reproduce this on PHP 5.2.7 using Windows Vista ------------------------------------------------------------------------ [2008-12-06 15:52:05] crrodriguez at opensuse dot org VERIFIED, but it is curl_multi_exec() that crashes. ------------------------------------------------------------------------ [2008-12-05 06:11:06] kyle at ifixit dot com Description: ------------ Multicurl crashes when using curl_copy_handle. Setup a multi request (A), copy the handlers, perform the first multi request (A) and clean it up, then perform a second request (B) with the copied handlers. PHP segfaults (a double free) on one of the handler close calls. If I don't manually free the multihandle, then the segfault is delayed until PHP cleans up the objects. Reproduce code: --------------- <? $count = 3; $mh = curl_multi_init(); $mh2 = curl_multi_init(); $conn = array(); $conn2 = array(); // Setup requests for ($i = 0; $i < $count; $i++) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/'); curl_setopt($ch, CURLOPT_TIMEOUT, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $conn[$i] = $ch; curl_multi_add_handle($mh, $ch); } // Perform first set of requests do { do { } while (curl_multi_exec($mh, $stillRunning) === CURLM_CALL_MULTI_PERFORM); } while ($stillRunning); for ($i = 0; $i < $count; $i++) { // Copy the completed handlers $conn2[$i] = curl_copy_handle($conn[$i]); curl_multi_add_handle($mh2, $conn2[$i]); // Remove the handlers from the first multihandler curl_multi_remove_handle($mh, $conn[$i]); curl_close($conn[$i]); } curl_multi_close($mh); echo "Initial requests Finished.\n"; // Perform the second set of requests do { do { } while (curl_multi_exec($mh2, $stillRunning) === CURLM_CALL_MULTI_PERFORM); } while ($stillRunning); // Remove the second set of completed handlers for ($i = 0; $i < $count; $i++) { curl_multi_remove_handle($mh2, $conn2[$i]); curl_close($conn2[$i]); } curl_multi_close($mh2); echo "Copied requests finished.\n"; ?> Expected result: ---------------- Initial requests Finished. Copied requests finished. Actual result: -------------- *** glibc detected *** php: double free or corruption (out): 0x0000000011e59630 *** ======= Backtrace: ========= /lib64/libc.so.6[0x35a906f4f4] /lib64/libc.so.6(cfree+0x8c)[0x35a9072b1c] /usr/local/lib/libcurl.so.4(curl_slist_free_all+0x23)[0x2aaaabeff893] php[0x4bd7ee] php(zend_llist_destroy+0x43)[0x83eb3c] php(zend_llist_clean+0x15)[0x83eba5] php[0x4c2094] php(list_entry_destructor+0x87)[0x85cd84] php(zend_hash_del_key_or_index+0x218)[0x859e8e] php(_zend_list_delete+0x69)[0x85c851] php(_zval_dtor_func+0x142)[0x84934a] php[0x839385] php(_zval_ptr_dtor+0x49)[0x8395f2] php(_zval_ptr_dtor_wrapper+0x21)[0x8496f2] php(zend_hash_destroy+0x70)[0x859fe1] php(_zval_dtor_func+0xfb)[0x849303] php[0x839385] php(_zval_ptr_dtor+0x49)[0x8395f2] php(_zval_ptr_dtor_wrapper+0x21)[0x8496f2] php(zend_hash_clean+0x70)[0x85a133] php[0x876e58] php[0x87796d] php(execute+0x2f4)[0x8764e8] php[0x876c7c] php[0x87796d] php(execute+0x2f4)[0x8764e8] php[0x876c7c] php[0x87796d] php(execute+0x2f4)[0x8764e8] php[0x876c7c] php[0x87796d] php(execute+0x2f4)[0x8764e8] php[0x876c7c] php[0x87796d] php(execute+0x2f4)[0x8764e8] php[0x876c7c] php[0x87796d] php(execute+0x2f4)[0x8764e8] php(zend_execute_scripts+0x290)[0x84be45] php(php_execute_script+0x38e)[0x7eb4f4] php(main+0x143e)[0x8e43d5] /lib64/libc.so.6(__libc_start_main+0xf4)[0x35a901d8a4] php[0x474859] ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=46756&edit=1