Edit report at http://bugs.php.net/bug.php?id=50688&edit=1
ID: 50688 Comment by: ajrattink at correct dot net Reported by: jcampbell at remindermedia dot com Summary: Using exceptions inside usort() callback function causes a warning Status: Assigned Type: Bug Package: Arrays related Operating System: Fedora Core 12 PHP Version: 5.*, 6 Assigned To: stas New Comment: I printed a debug line from my usort callback. It called debug_backtrace() to print the line and sourcefile in the debuglog. And therefor triggered the error. Even more, it did not sort. Maybe the phpmanual should state that usort() callbacks are not allowed to write loglines. I also think that usort() callbacks that DO change the array are perfectly legal, as long as they don't change the sort. Maybe your sorter code needs stackoverflow protection or whatever, but calling certain code 'invalid', because it causes your code to SEGV is a stupid way to solve a bug. Previous Comments: ------------------------------------------------------------------------ [2010-04-01 02:12:52] s...@php.net The reason seems to be that when making exception backtrace, debug_backtrace_get_args() uses SEPARATE_ZVAL_TO_MAKE_IS_REF() on arguments, which makes it look as if the argument was indeed modified (which usort is designed to protect against, since cmp callback is not supposed to modify the arguments) ------------------------------------------------------------------------ [2010-03-05 17:41:30] bernie at dcbl dot ca affects gentoo builds after > 5.2.10 (5.2.11, 5.2.11-r1, and 5.2.12) ------------------------------------------------------------------------ [2010-01-20 10:22:01] j...@php.net This was caused by the fix for bug #50006 (there weren't such checks before :) Stas, can you check this out? Didn't expect anyone to use exceptions, did you? :D ------------------------------------------------------------------------ [2010-01-08 01:51:56] federico dot lebron at gmail dot com The problem seems to be that usort checks the amount of references before and after the function call to see if the user-provided function modified it, but inside the function call, debug_backtrace_get_args adds a reference to the passed variables to use in e.g. debug_backtrace's "arg" element. ------------------------------------------------------------------------ [2010-01-07 19:42:30] jcampbell at remindermedia dot com Description: ------------ If the callback function used by usort handles an exception using a try/catch block, a warning is generated. The correct sorting is still done. This happens even when the exception & handling doesn't involve the variables. The example below is the usort example from the manual with only the try/catch block added. Reproducible in PHP 5.2.11 but not 5.2.9 Reproduce code: --------------- <?php function cmp($a, $b) { if ($a == $b) { return 0; } try { throw new Exception(); } catch (Exception $E) { } return ($a < $b) ? -1 : 1; } $a = array(3, 2, 5, 6, 1); usort($a, "cmp"); Expected result: ---------------- No warning message. Actual result: -------------- PHP Warning: usort(): Array was modified by the user comparison function in /home/jcampbell/usortExceptionWarning.php on line 19 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=50688&edit=1