php / php/php-src

PHP-FPM segfaults with Opcache enabled with Late Static Binding

Ouverte
#9,396 12 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Extension: opcache Status: Needs Triage
Langage dominant
C
Étoiles
40.4k
Forks
8.1k
Merge moyen
2 j 13 h
PR mergées (30 j)
96

Description

Description

PHP-FPM crashes then OPCache enabled(Even if I disable all low 16bits of optimization flags in opcache.optimization_level) with some pattern of Late static binding involved.

  • Only PHP-FPM is affected. Main PHP binary works fine(With opcache.enable_cli=1)
  • PHP-FPM works fine if OPCache is completely disabled(opcache.enable=0)
  • PHP-FPM 7.3 with OPCache works fine - 8.0 Crashes.
  • Specific case in dev crashes in ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER , but coredumps from our production shown other handlers from Zend/zend_vm_execute.h crashing the same way.

Unfortunately I can't create minimal working test case(I tried my best).
The only thing I know is that pattern like this causes it in the end(Note the constant having initial value via 'self' and later used as LSB via 'static'):

class TestClass
{
    const PHOENIX = '/usr/local/bin/grep';
    const CON1 = 'propose';
    const CON2 = self::CON1;
    const CON3 = 'r2';

    static public function crash($cmd, $params)
    {
        $paramsCmd = '';
        $fullCmd = static::CON3." '{$cmd}' {$paramsCmd}";
        $escalateOptimizer = ' '.static::CON2.' / '.static::CON3;
        return 13;
    }
}

Segmentation fault info:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000665bc6 in ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER ()
    at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:32987
32987                           if (EXPECTED(CACHED_PTR(opline->extended_value) == ce)) {
(gdb) bt
#0  0x0000000000665bc6 in ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER ()
    at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:32987
#1  0x00000000006971ac in execute_ex (ex=0x7feb82c141d0)
    at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:58077
#2  0x000000000069b692 in zend_execute (op_array=0x7feb82c02000, return_value=<optimized out>)
    at PHP_BUILD_ROOT/php-8.0.22/Zend/zend_vm_execute.h:59499
#3  0x0000000000635e2b in zend_execute_scripts (type=-2101263920, type@entry=8, retval=retval@entry=0x0,
    file_count=file_count@entry=3) at PHP_BUILD_ROOT/php-8.0.22/Zend/zend.c:1694
#4  0x00000000005d53a8 in php_execute_script (primary_file=primary_file@entry=0x7ffeda60fae0)
    at PHP_BUILD_ROOT/php-8.0.22/main/main.c:2543
#5  0x00000000004408e3 in main (argc=<optimized out>, argv=<optimized out>)
    at PHP_BUILD_ROOT/php-8.0.22/sapi/fpm/fpm/fpm_main.c:1914
(gdb) print ce
$1 = (zend_class_entry *) 0x42d0e058
(gdb) print opline->extended_value
$2 = 0
(gdb) print *opline
$3 = {handler = 0x6971a7 <execute_ex+21591>, op1 = {constant = 515, var = 515, num = 515, opline_num = 515,
    jmp_offset = 515}, op2 = {constant = 4294967152, var = 4294967152, num = 4294967152,
    opline_num = 4294967152, jmp_offset = 4294967152}, result = {constant = 128, var = 128, num = 128,
    opline_num = 128, jmp_offset = 128}, extended_value = 0, lineno = 27, opcode = 181 '\265',
  op1_type = 0 '\000', op2_type = 1 '\001', result_type = 2 '\002'}
(gdb)
PHP Version

PHP 8.0.22/8.0.23/8.024

8.1 tree seems to not be affected(Tested on 8.1.11).

Operating System

CentOS 7

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par reproduire l’exemple PHP-FPM fourni avec PHP 8.0.22–8.0.24, Opcache activé et les constantes de Late Static Binding, puis examinez le plantage dans Zend/zend_vm_execute.h au niveau de ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER. Comparez PHP-FPM avec le binaire CLI et avec PHP 8.1. Le travail est considéré comme terminé lorsque le segfault lié à Opcache a été identifié et corrigé avec un test de régression, bien que l’issue ne nomme aucun fichier de test et ne fournisse pas de cas minimal.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
c, php
Domaine
backend
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.