php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79535 PHP crashes with specific opcache.optimization_level
Submitted: 2020-04-29 10:44 UTC Modified: 2020-05-04 11:09 UTC
From: roland at nextendweb dot com Assigned:
Status: Closed Package: opcache
PHP Version: 7.3.17 OS: Windows, Linux
Private report: No CVE-ID: None
 [2020-04-29 10:44 UTC] roland at nextendweb dot com
Description:
------------
I was able to reproduce the crash with PHP 7.3.17 on Linux and PHP 7.3.3 on Windows. 

I have a Joomla installation with some extensions installed. The crash comes when opcache.optimization_level has the following values:
0xfffffaaf
0xfffffabf
0xfffffbbf
0xfffffbaf

The same crash does not happen if 
- opcode cache disabled 
- xdebug and opcode cache enabled
- opcode cache enabled and opcache.optimization_level has the following values:0xfffffa9f, 0xfffffadf, 0xfffffacf, 0xfffffccf, 0xfffffbcf, 0xffffffff

On PHP 7.3.3 Windows has no response in the browser the apache log says:
[mpm_winnt:notice] [pid 7112:tid 572] AH00428: Parent: child process 25244 exited with status 3221225477 -- Restarting.

On PHP 7.3.17 there was the last opened output buffer printed on the screen and functions with register_shutdown_function gets called.

WinDBG shows the following:
(5e9c.41f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
php7ts!object_and_properties_init+0xd:
00007ffb`798945ed 8b421c          mov     eax,dword ptr [rdx+1Ch] ds:00000000`0000001b=????????
0:225> g
(5e9c.41f4): Access violation - code c0000005 (!!! second chance !!!)
php7ts!object_and_properties_init+0xd:
00007ffb`798945ed 8b421c          mov     eax,dword ptr [rdx+1Ch] ds:00000000`0000001b=????????
0:225> g
(5e9c.41f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
php7ts!object_and_properties_init+0xd:
00007ffb`798945ed 8b421c          mov     eax,dword ptr [rdx+1Ch] ds:00000000`0000001b=????????


Call stack:
php7ts!object_and_properties_init+0xd
php7ts!zend_objects_clone_members+0xa00
php7ts!execute_ex+0x5f
php7ts!zend_call_function+0x2d0
php7ts!php_prefix_varname+0xdcfa
php7ts!zend_exception_set_previous+0xecc
php7ts!execute_ex+0x5f
php7ts!zend_execute+0x1a8
php7ts!zend_execute_scripts+0xb9
php7ts!php_execute_script+0x261
php7apache2_4+0x3df1
libhttpd!ap_run_handler+0x35
libhttpd!ap_invoke_handler+0x10f
libhttpd!ap_internal_redirect_handler+0x29a
libhttpd!ap_process_request+0xf
mod_http2+0x18822
mod_http2+0x18684
libhttpd!ap_run_process_connection+0x35
mod_http2+0x183e8
mod_http2+0x1c58e
ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x42
KERNEL32!BaseThreadInitThunk+0x14
ntdll!RtlUserThreadStart+0x21


I was unable to create test script as I'm not sure what could be the cause and the current environment is too complex.



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-04-29 11:22 UTC] roland at nextendweb dot com
I'm not sure if it help, but changing:
protected function newFormatter() {
    return new $className;
}

to 
protected function newFormatter() {
    return new Compressed;
}

seems to solve the issue, but it might be unrelated...
 [2020-04-29 15:34 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2020-04-29 15:34 UTC] cmb@php.net
Just to be sure: are there Xdebug and file_cache(_fallback)
involved?
 [2020-04-29 15:39 UTC] roland at nextendweb dot com
-Status: Feedback +Status: Assigned
 [2020-04-29 15:39 UTC] roland at nextendweb dot com
Xdebug is disabled when this crash happens.

Here is the phpinfo() related to opcache:

opcache.blacklist_filename	no value
opcache.consistency_checks	0
opcache.dups_fix	Off
opcache.enable	On
opcache.enable_cli	Off
opcache.enable_file_override	Off
opcache.error_log	no value
opcache.file_cache	no value
opcache.file_cache_consistency_checks	1
opcache.file_cache_fallback	1
opcache.file_cache_only	0
opcache.file_update_protection	2
opcache.force_restart_timeout	60
opcache.interned_strings_buffer	8
opcache.log_verbosity_level	1
opcache.max_accelerated_files	8192
opcache.max_file_size	0
opcache.max_wasted_percentage	5
opcache.memory_consumption	512
opcache.mmap_base	no value
opcache.opt_debug_level	0
opcache.optimization_level	0xfffffbbf
opcache.preferred_memory_model	no value
opcache.protect_memory	0
opcache.restrict_api	no value
opcache.revalidate_freq	10
opcache.revalidate_path	Off
opcache.save_comments	1
opcache.use_cwd	On
opcache.validate_permission	Off
opcache.validate_timestamps	On
 [2020-04-29 16:32 UTC] cmb@php.net
-Status: Assigned +Status: Open -Assigned To: cmb +Assigned To:
 [2020-04-29 16:32 UTC] cmb@php.net
When file_cache is enabled, and you switch Xdebug on and off,
crashes are to be expected.  That issue has already been reported
as bug #75886.
 [2020-04-29 16:35 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2020-04-29 16:35 UTC] cmb@php.net
Ah, but file_cache is not enabled in your case!

Can you please try with a recent PHP version on Windows, and
provide a *debug* backtrace, see
<https://bugs.php.net/bugs-generating-backtrace-win32.php>.
 [2020-04-29 16:37 UTC] roland at nextendweb dot com
-Status: Feedback +Status: Open
 [2020-04-29 16:37 UTC] roland at nextendweb dot com
I didn't originally used xdebug and xdebug was only on a single server installed. I was able to reproduce this crash on 3 different server and on two xdebug was not installed. So I do not think it is xdebug related. 

If I added opcache_reset() to my index.php it was good all the time. After removed, it crashed.
 [2020-04-30 07:25 UTC] cmb@php.net
-Status: Open +Status: Feedback
 [2020-04-30 07:25 UTC] cmb@php.net
Thanks for the further info!

Can you please try with a recent PHP version on Windows, and
provide a *debug* backtrace, see
<https://bugs.php.net/bugs-generating-backtrace-win32.php>.
 [2020-04-30 07:57 UTC] roland at nextendweb dot com
-Status: Feedback +Status: Assigned
 [2020-04-30 07:57 UTC] roland at nextendweb dot com
Can you download it from here? Is it contains what you need?

https://www.dropbox.com/s/qr612f6mkyb14pc/MultipleDumps_MultipleRules.mht?dl=1
 [2020-04-30 09:06 UTC] cmb@php.net
-Status: Assigned +Status: Open
 [2020-04-30 09:06 UTC] cmb@php.net
Thanks for the analysis report using PHP 7.3.17!  It contains the
following slightly different backtrace (unfortunately, again
without line numbers, but these might not be that helpful anyway):

php7ts!object_and_properties_init+d 
php7ts!ZEND_NEW_SPEC_VAR_UNUSED_HANDLER+40 
php7ts!execute_ex+5f 
php7ts!zend_call_function+2d0 
php7ts!zif_call_user_func_array+da 
php7ts!ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_HANDLER+ac 
php7ts!execute_ex+5f 
php7ts!zend_execute+1a8 
php7ts!zend_execute_scripts+b9 
php7ts!php_execute_script+261 
php7apache2_4!php_handler+591 

Anyhow, assuming that the OPcache instance isn't shared across
different PHP configurations, it looks like some combinations of
optimizations are not properly supported, which may result in
segfaults (likely trying to read offsets of NULL).

@roland, I suggest to stick with one of the working optimization
levels or just the default (0x7FFEBFFF).
 [2020-04-30 09:06 UTC] cmb@php.net
-Status: Assigned +Status: Open -Assigned To: cmb +Assigned To:
 [2020-04-30 10:00 UTC] nikic@php.net
I can't do anything about this without a way to reproduce.

The only suggestion I have is to make sure that the optimization level is masked with 0xfffeffff, which disables an unsafe (in the sense of "can crash" rather than "can cause misbehavior") optimization, though I doubt that is the actual cause.
 [2020-04-30 13:10 UTC] roland at nextendweb dot com
Good news! I was able to create a reduced test case where this bug happens. Could you verify that the crash happens for you too?

https://www.dropbox.com/s/3jp5dzyfzmurxcc/php-bug-79535.zip?dl=1

Run index.php

The desired output: html{padding:0;}Hello World


If you open LessCompiler.php

and replace
    protected function newFormatter() {

        $className = Compressed::class;

        return new $className;
    }

with 

    protected function newFormatter() {

        return new Compressed();
    }

It will work fine. Also when you invalidate opcode cache for LessCompiler.php, then it works for the first load and every other try crashes.
 [2020-05-04 10:29 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2020-05-04 10:29 UTC] nikic@php.net
Can confirm that the test case crashes at opcache.optimization_level=0xfffffaaf (but not at the default level).
 [2020-05-04 11:09 UTC] nikic@php.net
Minimal:

function create() {
    $name = stdClass::class;
    return new $name;
}
var_dump(create());

with -d opcache.optimization_level=0x000000a0 (only SCCP)

==9022== Conditional jump or move depends on uninitialised value(s)
==9022==    at 0xADEAEF: ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER (zend_vm_execute.h:31745)
==9022==    by 0xB096C8: execute_ex (zend_vm_execute.h:58853)
==9022==    by 0xB0B8B1: zend_execute (zend_vm_execute.h:60939)
==9022==    by 0xA2FD73: zend_execute_scripts (zend.c:1568)
==9022==    by 0x99562D: php_execute_script (main.c:2639)
==9022==    by 0xB0E6C3: do_cli (php_cli.c:997)
==9022==    by 0xB0F8F5: main (php_cli.c:1393)

Has something to do with the FETCH_CLASS cache slot.
 [2020-05-04 12:52 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7c1316ec6a726adaf96b9101054b85bbd763c14f
Log: Fixed bug #79535
 [2020-05-04 12:52 UTC] nikic@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Aug 11 01:01:25 2020 UTC