krakjoe / uopz

User Operations for Zend
Other
358 stars 47 forks source link

Repro pattern for SIGSEGV (11) with PHPUnit 9.5 #140

Closed keywinf closed 3 years ago

keywinf commented 3 years ago

Hi,

I'm encountering a blocking segfault (60/70% of the time) caused by uopz_del_function, with the current last commit of uopz master branch, phpunit/phpunit:^9.5 in my composer file, inside a docker image with Symfony 4.4, and php 8.0.2.

(1) This works fine, doing php -f OneTest.php, showing that uopz is working fine under basic environment:

<?php

require __DIR__ . '/vendor/autoload.php';

use PHPUnit\Framework\TestCase;

class Foo {}

class OneTest extends TestCase
{
    public function it_does()
    {
        $i = 1;

        uopz_add_function(Foo::class, 'f', function () use ($i) {
            return 'OK';
        });

        uopz_del_function(Foo::class, 'f'); // THIS WORKS
    }
}

(new OneTest)->it_does();

(2) But this won't, doing phpunit OneTest.php:

<?php

namespace My\Namespace;

use PHPUnit\Framework\TestCase;

class Foo {}

class OneTest extends TestCase
{
    /** @test */
    public function it_does()
    {
        $i = 1;

        uopz_add_function(Foo::class, 'f', function () use ($i) {
            return 'OK';
        });

        uopz_del_function(Foo::class, 'f'); // THIS DOES NOT WORK: SEGFAULT
    }
}

(3) If I remove the use ($i), it works again via phpunit OneTest.php:

<?php

namespace My\Namespace;

use PHPUnit\Framework\TestCase;

class Foo {}

class OneTest extends TestCase
{
    /** @test */
    public function it_does()
    {
        $i = 1;

        uopz_add_function(Foo::class, 'f', function () {
            return 'OK';
        });

        uopz_del_function(Foo::class, 'f'); // THIS WORKS
    }
}

Any idea?

Here is the gdb php backtrace (bt) for (2):

#0  0x000055aa35cc9dd1 in _emalloc ()
#1  0x000055aa35cba184 in lex_scan ()
#2  0x000055aa35ccf83a in ?? ()
#3  0x000055aa35cb215e in zendparse ()
#4  0x000055aa35cb4ae4 in ?? ()
#5  0x000055aa35cb656a in compile_file ()
#6  0x000055aa35b8e0d9 in ?? ()
#7  0x000055aa35cb65e2 in compile_filename ()
#8  0x000055aa35d1fc05 in ?? ()
#9  0x000055aa35d3570a in ?? ()
#10 0x000055aa35d51b3c in execute_ex ()
#11 0x000055aa35ce35ea in zend_call_function ()
#12 0x000055aa35ce3a25 in zend_call_known_function ()
#13 0x000055aa35bbff7a in ?? ()
#14 0x000055aa35ce27c5 in zend_lookup_class_ex ()
#15 0x000055aa35ce3d0c in zend_fetch_class_by_name ()
#16 0x000055aa35d33177 in ?? ()
#17 0x000055aa35d50ad6 in execute_ex ()
#18 0x000055aa35d58e0e in zend_execute ()
#19 0x000055aa35cf0d3d in zend_execute_scripts ()
#20 0x000055aa35c8e35e in php_execute_script ()
#21 0x000055aa35d7e5ae in ?? ()
#22 0x000055aa35a1a80b in ?? ()
#23 0x00007f9e1acb009b in __libc_start_main (main=0x55aa35a1a3c0, argc=5, argv=0x7ffc6c329728, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffc6c329718) at ../csu/libc-start.c:308
#24 0x000055aa35a1af4a in _start ()

Here is my phpunit.xml(.dist):

<?xml version="1.0" encoding="UTF-8"?>

<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.1/phpunit.xsd"
    backupGlobals="false"
    colors="true"
    bootstrap="tests/tests.bootstrap.php"
>
    <php>
        <ini name="error_reporting" value="-1" />
        <ini name="memory_limit" value="10G" />

        <env name="KERNEL_CLASS" value="App\Kernel" />
        <env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" />

        <env name="TESTING" value="1" />

<!--        <env name="SPX_ENABLED" value="1" />-->
<!--        <env name="SPX_BUILTINS" value="1" />-->
<!--        <env name="SPX_REPORT" value="full" />-->
    </php>

    <testsuites>
        <testsuite name="ALL">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>

    <listeners>
        <listener class="AppTest\TestListener">
        </listener>
    </listeners>
</phpunit>

Here is my php.ini, just in case:

[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 17
disable_functions =
disable_classes =
realpath_cache_size = 4096k
realpath_cache_ttl = 600
zend.enable_gc = On
expose_php = On
max_execution_time = 300
max_input_time = 60
memory_limit = -1
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 10G
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 10G
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
[CLI Server]
cli_server.color = On
[Date]
date.timezone = Europe/Paris
[Pdo_mysql]
pdo_mysql.cache_size = 2000
pdo_mysql.default_socket =
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = On
[SQL]
sql.safe_mode = Off
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"
[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off
[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
[bcmath]
bcmath.scale = 0
[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 0
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"
[Assertion]
zend.assertions = -1
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled = 1
soap.wsdl_cache_dir = "/tmp"
soap.wsdl_cache_ttl = 86400
soap.wsdl_cache_limit = 5
[ldap]
ldap.max_links = -1
[opcache]
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.max_accelerated_files=20000

Don't hesitate to ask for more details if needed. Thanks in advance!

uij86 commented 3 years ago

Hi @keywinf, same problem here, have you tried disabling opcache? I would be curious to know if it can solve the problem

keywinf commented 3 years ago

@uij86 disabling opcache did not solve my case (neither the basic nor the CLI one)

keywinf commented 3 years ago

thanks @krakjoe