|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2020-02-10 12:41 UTC] jakub at tuenti dot com
Description:
------------
Preloading a class with a static variable causes php-fpm to segfault during exit. I have tested in debian docker images with php 7.4.2 and 7.4.3RC1. Preloading works fine before the exit.
root@a37b6a321c52:/# php-fpm -dzend_extension=opcache -dopcache.preload=/preload.php -dopcache.preload_user=root
[10-Feb-2020 12:34:41] NOTICE: fpm is running, pid 579
[10-Feb-2020 12:34:41] NOTICE: ready to handle connections
^C[10-Feb-2020 12:34:42] NOTICE: Terminating ...
[10-Feb-2020 12:34:42] NOTICE: exiting, bye-bye!
Segmentation fault (core dumped)
I have included a backtrace for php 7.4.2
Test script:
---------------
# /preload.php
<?php
opcache_compile_file("/test.php");
# /test.php
<?php
class A {
static $x;
}
Actual result:
--------------
#0 zend_cleanup_internal_class_data (ce=0x7f3d0fcbe9a0) at ./Zend/zend_types.h:441
static_members = 0x303a783a746f6f72
p = 0x303a783a746f6f72
end = 0x303a783a746f6f82
#1 0x000055e6aca38988 in destroy_zend_class (zv=<optimized out>) at ./Zend/zend_opcode.c:253
op_array = <optimized out>
prop_info = <optimized out>
ce = 0x7f3d0fcbe9a0
fn = <optimized out>
#2 0x000055e6aca53905 in zend_hash_destroy (ht=0x55e6addef390) at ./Zend/zend_hash.c:1541
p = 0x55e6ade943d0
end = 0x55e6ade943f0
#3 0x000055e6aca43b36 in zend_shutdown () at ./Zend/zend.c:1054
No locals.
#4 0x000055e6ac9e372a in php_module_shutdown () at ./main/main.c:2477
module_number = <optimized out>
module_number = <optimized out>
cb = <optimized out>
#5 php_module_shutdown () at ./main/main.c:2454
cb = <optimized out>
#6 0x000055e6acad6239 in fpm_php_cleanup (which=<optimized out>, arg=<optimized out>) at ./sapi/fpm/fpm/fpm_php.c:198
No locals.
#7 0x000055e6acace9bd in fpm_cleanups_run (type=type@entry=4) at ./sapi/fpm/fpm/fpm_cleanup.c:43
c = 0x55e6adef6580
cl = <optimized out>
#8 0x000055e6acad6ee4 in fpm_pctl_exit () at ./sapi/fpm/fpm/fpm_process_ctl.c:71
__func__ = "fpm_pctl_exit"
#9 fpm_pctl_action_last () at ./sapi/fpm/fpm/fpm_process_ctl.c:118
No locals.
#10 0x000055e6acad7b3b in fpm_pctl (action=2, new_state=0) at ./sapi/fpm/fpm/fpm_process_ctl.c:260
__func__ = "fpm_pctl"
#11 fpm_pctl_child_exited () at ./sapi/fpm/fpm/fpm_process_ctl.c:260
No locals.
#12 0x000055e6acace51b in fpm_children_bury () at ./sapi/fpm/fpm/fpm_children.c:266
wp = 0x55e6adef6c90
tv1 = {tv_sec = 10543, tv_usec = 512922}
tv2 = {tv_sec = 22, tv_usec = 495922}
buf = "on signal 15 (SIGTERM)\000\000\060\254\267\204\377\177\000\000\020/\266\204\377\177\000\000\000\304\370\317\001\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\360.\266\204\377\177\000\000@/\266\204\377\177\000\000@J\304\254\346U\000\000\317\367S\343\245\233\304 \020/\266\204\377\177\000\000\366\237\244\031=\177\000\000\f\000\000\000\000\000\000\000\366\237\244\031=\177\000"
severity = 1
restart_child = 1
status = 15
pid = 919
child = <optimized out>
__func__ = "fpm_children_bury"
#13 0x000055e6acad3703 in fpm_event_fire (ev=0x55e6acc44b60 <children_bury_timer>) at ./sapi/fpm/fpm/fpm_events.c:487
No locals.
#14 fpm_event_loop (err=err@entry=0) at ./sapi/fpm/fpm/fpm_events.c:467
ev = 0x55e6acc44b60 <children_bury_timer>
next = 0x55e6adefffe0
--Type <RET> for more, q to quit, c to continue without paging--
q = 0x55e6adeffd70
ms = <optimized out>
tmp = <optimized out>
timeout = <optimized out>
ret = <optimized out>
q2 = <optimized out>
now = {tv_sec = 10543, tv_usec = 512855}
signal_fd_event = {fd = 5, timeout = {tv_sec = 0, tv_usec = 0}, frequency = {tv_sec = 0, tv_usec = 0}, callback = 0x55e6acad3890 <fpm_got_signal>, arg = 0x0, flags = 2, index = 5, which = 2}
__func__ = "fpm_event_loop"
#15 0x000055e6acacdd47 in fpm_run (max_requests=0x7fff84b630fc) at ./sapi/fpm/fpm/fpm.c:113
wp = 0x0
#16 0x000055e6ac8adad2 in main (argc=6, argv=0x7fff84b636f8) at ./sapi/fpm/fpm/fpm_main.c:1854
exit_status = 0
c = -1
use_extended_info = 0
file_handle = {handle = {fp = 0x0, stream = {handle = 0x0, isatty = 442194688, reader = 0x1, fsizer = 0x0, closer = 0x7f3d199c3490 <ptmalloc_init>}}, filename = 0x7f3d1a5a7628 "\274",
opened_path = 0x7fff84b635f0, type = (ZEND_HANDLE_STREAM | unknown: 442221944), free_filename = 61 '=', buf = 0x7f3d19afec40 <main_arena> "", len = 139900400692384}
orig_optind = 1
orig_optarg = 0x0
ini_entries_len = 80
max_requests = 0
requests = 0
fcgi_fd = 0
request = <optimized out>
fpm_config = <optimized out>
fpm_prefix = 0x0
fpm_pid = 0x0
test_conf = 0
force_daemon = -1
force_stderr = 0
php_information = 0
php_allow_to_run_as_root = 1
ret = <optimized out>
__func__ = "main"
__orig_bailout = <optimized out>
__bailout = <optimized out>
__str = <optimized out>
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 03:00:01 2025 UTC |
This patch seems to fix it: diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index c7d73a999a..0c8722418c 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -4233,9 +4233,11 @@ static void preload_load(void) EG(persistent_classes_count) = EG(class_table)->nNumUsed; } if (CG(map_ptr_last) != ZCSG(map_ptr_last)) { + size_t old_map_ptr_last = CG(map_ptr_last); CG(map_ptr_last) = ZCSG(map_ptr_last); CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096); CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1); + memset(CG(map_ptr_base) + old_map_ptr_last, 0, (CG(map_ptr_last) - old_map_ptr_last) * sizeof(void *)); } } I assume the problem is that the relevant process does not execute a PHP request, as such never goes through zend_active and as such never initializes the map region. Not positive on this being the right fix though, also wondering if it's fine to just zero the whole map area there.