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

Reply via email to