Repository navigation
Segmentation fault in PHP 8.1 #8461
Copy link
Copy link
Closed
Description
Description
The problem is quite difficult to reproduce.
Need to change php files when running specific application in php-fpm.
Steps to reproduce:
- Turn on JIT, Opcache
opcache.jit_buffer_size=100M
opcache.jit=1255
- Extract
bugphp.zip - Use
abto executerun.phpfrombugphp.zip:
ab -n 5000 -c 20 http://localhost/run.phpApplication touches UniqueList.php to make it modified for the OPcache.
Segmentation faults:
[29-Apr-2022 15:07:30] NOTICE: ready to handle connections
[29-Apr-2022 15:07:33] WARNING: [pool www] child 338824 exited on signal 11 (SIGSEGV - core dumped) after 2.980459 seconds from start
[29-Apr-2022 15:07:33] NOTICE: [pool www] child 338841 started
[29-Apr-2022 15:07:33] WARNING: [pool www] child 338827 exited on signal 11 (SIGSEGV - core dumped) after 2.980157 seconds from start
[29-Apr-2022 15:07:33] NOTICE: [pool www] child 338842 started
[29-Apr-2022 15:07:33] WARNING: [pool www] child 338826 exited on signal 11 (SIGSEGV - core dumped) after 2.999109 seconds from start
Backtrace:
#0 0x00000000008a47d1 in ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER ()
at /home/Oleg.Stepanischev/php-src/Zend/zend_vm_execute.h:33346
#1 0x00000000008cdcd3 in execute_ex (ex=0x7fb8c7c14020) at /home/Oleg.Stepanischev/php-src/Zend/zend_vm_execute.h:58689
#2 0x00000000008cf41b in zend_execute (op_array=0x7fb8c7c67000, return_value=0x0)
at /home/Oleg.Stepanischev/php-src/Zend/zend_vm_execute.h:60123
#3 0x00000000008231b3 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /home/Oleg.Stepanischev/php-src/Zend/zend.c:1792
#4 0x000000000078bbd4 in php_execute_script (primary_file=0x7ffdc50da360) at /home/Oleg.Stepanischev/php-src/main/main.c:2538
#5 0x00000000009901d9 in main (argc=2, argv=0x7ffdc50da578) at /home/Oleg.Stepanischev/php-src/sapi/fpm/fpm/fpm_main.c:1914
Bisect found the commit that contains the problem: 4b79dba
Disabling inheritance cache solves the problem.
The UniqueList class has a child class UniqueListLast that uses some of the parent class's constants. And the modification of the parent class somehow leads to the problem.
Possible related to #7817
PHP Version
PHP 8.1
Operating System
AlmaLinux release 8.5 (Arctic Sphynx)
Reacted by Evgeny Stepanischev, Jiří Černý, Serhii Semenko, Dmitriy Pertsev, Ondřej Misák, Kostadin A. and Niklas
Reacted by Thibault Buathier, Claude Bing and Jiří Černý
Reacted by Jiří Černý
Reacted by Jiří Černý
Activity
meinemitternacht commentedon Apr 29, 2022
I'm pretty sure this is the source of the problems in #7817. In our application (embedded hardware), there are several PHP files that are generated by other C programs which are overwritten often.
bolknote commentedon Apr 29, 2022
Wow! Great job, Oleg!
oleg-st commentedon May 4, 2022
After some research, I found that the problem occurs here https://github.com/php/php-src/blob/PHP-8.1/ext/opcache/jit/zend_jit_x86.dasc#L10044
func->op_array.run_time_cache__ptrchanges when the file with the called function is reloaded. I don't know if it was intended or not. This causes therun_time_cacheto be loaded incorrectly.arnaud-lb commentedon May 4, 2022
I confirm this. The run_time_cache__ptr of the sub class constructor changes when the parent class is recompiled.
The crash happens because the old run_time_cache offset is still used by the generated code.
Change of the run_time_cache__ptr happens during zend_do_link_class, when the inheritance cache is persisted.
Reverting the changes made by JIT on the op array would fix the issue. I think that we are not supposed to reuse the JIT code here.
oleg-st commentedon May 5, 2022
A simple fix is to remove 2 branches with specific cases and leave one generic:
https://github.com/php/php-src/blob/PHP-8.1/ext/opcache/jit/zend_jit_x86.dasc#L10069
It's also strange that the second branch uses
run_time_cache__ptras an offset, but the first branch has already fully covered this case.To remove the JIT code in this case, I think we need to remove the JIT code of all callers when the callee code changes.
oleg-st commentedon May 12, 2022
Tested with #8535, everything works fine for me
rs-orlov commentedon Sep 8, 2023
@oleg-st what do you mean by "Disabling inheritance cache ...", did you just dropped commit and built php without it? Or is there a reasonably small patch which makes inheritance cache effectively disabled?
We have another issue with inheritance cache. It blocks us from upgrading php version. Considering amount of time issue hangs without any movement, disabling inheritance cache (even by patching php) seems to be not so bad alternative.
oleg-st commentedon Sep 10, 2023
@rs-orlov
This can be done by commenting out these 2 lines:
php-src/ext/opcache/ZendAccelerator.c
Lines 3342 to 3343 in bec1552
Fix: Disable OPcache JIT to prevent SIGSEGV with sodium encryption