Description:
------------
Using a self built PHP 5.6.5, opcache enabled:
switch(ARBITRARYCONSTANTS) misbehaves: goes to the default case, unless the matching thing is the first case.
opcache is enabled like this:
zend_extension=/opt/php/extensions/opcache.so
opcache.enable_cli=1
Also happens under mod_php without opcache.enable_cli. No other opcache settings made, but happens also with our usual production settings, so that should not matter
The result is usually what I show under "actual result", below, but on some runs I also see a segmentation fault, or the correct behaviour.
I can reproduce the problem when using global "const MYCONST = 'foo';", but apparently _not_ with a class constant (class foo { const MYCONST = 'foo'; }
Will create a debug build of PHP soon and try to capture a backtrace for a test run where it runs into a segmentation violation. Might take some time, though...
Test script:
---------------
<?php
define('MYCONST', 'foo');
function goodswitch() {
switch(MYCONST) {
case 'foo': return 'foo';
case 'bar': return 'bar';
default: return 'default';
}
}
function badswitch() {
switch(MYCONST) {
case 'bar': return 'bar';
case 'foo': return 'foo';
default: return 'default';
}
}
var_dump(goodswitch());
var_dump(badswitch());
?>
Expected result:
----------------
string(3) "foo"
string(3) "foo"
Actual result:
--------------
string(3) "foo"
string(7) "default"

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

[2015-02-12 09:20 UTC] php at bof dot de

I cannot get it to segfault / dump core on an --enable-debug build. Weird. Tried it a few hundred times. However the issue is still there (outputs foo and default).
With the production build, identical in all other regards, I can get it to segfault in one of about 10 runs. Here is a backtrace of such a run, for whatever that's worth:
Core was generated by `php -d opcache.enable_cli=1 /home/patrick/webdev/switch_const_myconst.php'.
Program terminated with signal 11, Segmentation fault.
#0 0x0000000000000021 in ?? ()
(gdb) bt
#0 0x0000000000000021 in ?? ()
#1 0x0000000000853d3b in zend_hash_destroy (ht=0x7f941c441e18)
at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend_hash.c:548
#2 0x0000000000844893 in _zval_dtor_func (zvalue=0x7f941c4401b0)
at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend_variables.c:45
#3 0x000000000087368a in _zval_dtor (execute_data=0x7f941c4401d0)
at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend_variables.h:35
#4 ZEND_FREE_SPEC_TMP_HANDLER (execute_data=0x7f941c4401d0)
at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend_vm_execute.h:7956
#5 0x00000000008b07c9 in execute_ex (execute_data=0x7f941c4401d0)
at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend_vm_execute.h:363
#6 0x00007f941467947b in xdebug_execute_ex (execute_data=0x7f941c4401d0)
at /usr/src/phb/build/release-5.6.5/xdebug/xdebug.c:1437
#7 0x00000000008e7ac2 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend_vm_execute.h:592
#8 0x00000000008b07c9 in execute_ex (execute_data=0x7f941c4400e0)
at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend_vm_execute.h:363
#9 0x00007f941467947b in xdebug_execute_ex (execute_data=0x7f941c4400e0)
at /usr/src/phb/build/release-5.6.5/xdebug/xdebug.c:1437
#10 0x00000000008472d4 in zend_execute_scripts (type=8, retval=0x0,
file_count=3) at /usr/src/phb/build/release-5.6.5/php-src/Zend/zend.c:1341
#11 0x00000000007e3bfe in php_execute_script (primary_file=0x7fffaabc56f0)
at /usr/src/phb/build/release-5.6.5/php-src/main/main.c:2584
#12 0x00000000008eaf89 in do_cli (argc=4, argv=0x1f00e90)
at /usr/src/phb/build/release-5.6.5/php-src/sapi/cli/php_cli.c:994
#13 0x00000000008eb91c in main (argc=4, argv=0x1f00e90)
at /usr/src/phb/build/release-5.6.5/php-src/sapi/cli/php_cli.c:1378

Thanks laruence for having a go at it.
I tried your gist with 5.6.6RC1 - the issue is still the same, although I don't get a valgrind error any more (which was sporadic before, too)
No other negative impact seen with your gist applied, though - no new test suite failures seen.

Sorry, Laruence, have to reopen.
I test-built PHP 5.6.6RC1 with your patch applied.
Using your test case from the git commit today, I can see that that test case now works (okey two times), and with my previous 5.6.5 build it fails (bad two times).
However, my own reproducer from comment [2015-02-12 09:57 UTC] here, still fails.
Please let me know if you need any more information (configure arguments and such) for my build.