Skip to content

Commit 757781a

Browse files
committed
Fix GH-16577: EG(strtod_state).freelist leaks with opcache.preload
This happens because on ZTS we execute `executor_globals_ctor` which reset the `freelist` and `p5s` pointers, while on NTS we don't. On NTS we can reuse the caches but on ZTS we can't, the easiest fix is to call `zend_shutdown_strtod` when preloading is shut down. This regressed in GH-13974 and therefore only exists in PHP 8.4 and higher. Closes GH-16602.
1 parent d6839f7 commit 757781a

File tree

4 files changed

+30
-0
lines changed

4 files changed

+30
-0
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ PHP NEWS
55
- Core:
66
. Fixed bug GH-16574 (Incorrect error "undefined method" messages).
77
(nielsdos)
8+
. Fixed bug GH-16577 (EG(strtod_state).freelist leaks with opcache.preload).
9+
(nielsdos)
810

911
- GD:
1012
. Fixed bug GH-16559 (UBSan abort in ext/gd/libgd/gd_interpolation.c:1007).

ext/opcache/ZendAccelerator.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,6 +4462,12 @@ static zend_result accel_preload(const char *config, bool in_child)
44624462
/* Release stored values to avoid dangling pointers */
44634463
zend_shutdown_executor_values(/* fast_shutdown */ false);
44644464

4465+
/* On ZTS we execute `executor_globals_ctor` which reset the freelist and p5s pointers, while on NTS we don't.
4466+
* We have to clean up the memory before the actual request takes place to avoid a memory leak. */
4467+
#ifdef ZTS
4468+
zend_shutdown_strtod();
4469+
#endif
4470+
44654471
/* We don't want to preload constants.
44664472
* Check that zend_shutdown_executor_values() also destroys constants. */
44674473
ZEND_ASSERT(zend_hash_num_elements(EG(zend_constants)) == EG(persistent_constants_count));

ext/opcache/tests/gh16577.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
var_dump(1.5);

ext/opcache/tests/gh16577.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-16577 (EG(strtod_state).freelist leaks with opcache.preload)
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
opcache.preload={PWD}/gh16577.inc
8+
--EXTENSIONS--
9+
opcache
10+
--SKIPIF--
11+
<?php
12+
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
13+
?>
14+
--FILE--
15+
<?php
16+
echo "Done\n";
17+
?>
18+
--EXPECT--
19+
float(1.5)
20+
Done

0 commit comments

Comments
 (0)