php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79548 Preloading segfault with inherited method using static variable
Submitted: 2020-04-30 15:33 UTC Modified: 2020-05-04 14:26 UTC
From: luca at sungazer dot io Assigned:
Status: Closed Package: opcache
PHP Version: 7.4.5 OS: Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: luca at sungazer dot io
New email:
PHP Version: OS:

 

 [2020-04-30 15:33 UTC] luca at sungazer dot io
Description:
------------
Configuration: 
* Custom image built from https://hub.docker.com/_/php
* Nginx + PHP-FPM 
* Symfony 5.0.8
* PHP 7.4.5
* Preloading enabled (preload file generated by Symfony)

Description:
When using the Symfony Cache component, php-fpm was terminating with SIGSEGV whenever I wanted to call the cache get() method. This happened only when preloading was enabled.

After further investigation, I saw that the segmentation fault happens at this line of Symfony's ContractsTrait https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Cache/Traits/ContractsTrait.php#L58

i.e. at the declaration of a static variable inside a private method of a Trait.

A similar issue was reported on Symfony's issue list as well: https://github.com/symfony/symfony/issues/36328

As a workaround, I tried moving the declaration outside the function (i.e. at trait level `private static $setMetadata`) and then code started working as intended. Disabling preloading also fixes the issue.

Test script:
---------------
Please see the following repository: https://github.com/luca-nardelli/symfony-cache-segfault-reproducer/tree/master


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-05-04 14:08 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2020-05-04 14:08 UTC] nikic@php.net
Minimal:

// preload.php
trait T {
    public function test() {
        static $foo;
    }
}
class A {
    use T;
}
class B extends A {}

// script.php
(new B)->test();

Trace:

#0  0x0000555555da20e6 in _zend_is_inconsistent (ht=0x0, 
    file=0x55555664f608 "/home/nikic/php-7.4/Zend/zend_hash.c", line=2045)
    at /home/nikic/php-7.4/Zend/zend_hash.c:54
#1  0x0000555555da8abb in zend_array_dup (source=0x0) at /home/nikic/php-7.4/Zend/zend_hash.c:2045
#2  0x0000555555e6131d in ZEND_BIND_STATIC_SPEC_CV_UNUSED_HANDLER ()
    at /home/nikic/php-7.4/Zend/zend_vm_execute.h:46850
#3  0x0000555555e6c0a0 in execute_ex (ex=0x7fffeb613020)
    at /home/nikic/php-7.4/Zend/zend_vm_execute.h:57622
#4  0x0000555555e6c594 in zend_execute (op_array=0x7fffeb67a300, return_value=0x7fffffffc550)
    at /home/nikic/php-7.4/Zend/zend_vm_execute.h:57922
 [2020-05-04 14:19 UTC] nikic@php.net
The trait usage here was a red herring, this is sufficient:

class A {
    public function test() {
        static $foo;
    }
}

class B extends A {}
 [2020-05-04 14:26 UTC] nikic@php.net
-Summary: Segfault when using static inline variable inside a trait +Summary: Preloading segfault with inherited method using static variable
 [2020-05-04 14:30 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=21a9ad910bc1a890ca4bddc4d4239c2e17d4c6a6
Log: Fixed bug #79548
 [2020-05-04 14:30 UTC] nikic@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC