Bug #75579 [Ana]: All Interned Strings Free memory used and PHP crashes
| From: | nikic@php.net | Date: | Wed, 20 Dec 2017 17:38:02 +0000 |
| Subject: | Bug #75579 [Ana]: All Interned Strings Free memory used and PHP crashes | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-213188@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75579&edit=1
ID: 75579
Updated by: nikic@php.net
Reported by: post at minhost dot no
Summary: All Interned Strings Free memory used and PHP
crashes
Status: Analyzed
Type: Bug
Package: opcache
Operating System: CentOS 7.4
PHP Version: 7.1.12
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
@post at minhost dot no: How did you apply the patch? It looks to me like you copy&pasted the
entire file from the master branch maybe?
Here's a variant of the patch that should work on 7.1: https://gist.github.com/nikic/31e8e4510a0ed84cea543b50d78ae431
It can be applied using "git apply" or "patch".
Previous Comments:
------------------------------------------------------------------------
[2017-12-20 17:27:40] post at minhost dot no
@dmitry: I applied your patch to PHP 7.1.13RC1, but I get errors when compiling PHP with your patch,
so I am not able to compile it. Please try to compile it your self to see the problem. Please look
into this. Here is the complete output with errors:
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c: In function
'zend_file_cache_serialize_ast':
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:286:49: error:
'ZEND_AST_CONSTANT' undeclared (first use in this function)
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:286:49: note: each
undeclared identifier is reported only once for each function it appears in
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c: In function
'zend_file_cache_serialize_zval':
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:349:5: warning:
passing argument 1 of 'zend_file_cache_serialize_ast' makes pointer from integer without a
cast [enabled by default]
zend_file_cache_serialize_ast(GC_AST(ast), script, info, buf);
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:278:13: note:
expected 'struct zend_ast *' but argument is of type 'int'
static void zend_file_cache_serialize_ast(zend_ast *ast,
^
In file included from
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:21:0:
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c: In function
'zend_file_cache_serialize_op_array':
/usr/local/directadmin/custombuild/php-7.1.13RC1/Zend/zend_compile.h:657:27: error:
'zend_op' has no member named 'literals'
RT_CONSTANT_EX((op_array)->literals, node)
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/Zend/zend_compile.h:622:20: note: in definition of
macro 'RT_CONSTANT_EX'
((zval*)(((char*)(base)) + (node).constant))
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:423:28: note: in
expansion of macro 'RT_CONSTANT'
opline->op1.constant = RT_CONSTANT(opline, opline->op1) - literals;
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/Zend/zend_compile.h:657:27: error:
'zend_op' has no member named 'literals'
RT_CONSTANT_EX((op_array)->literals, node)
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/Zend/zend_compile.h:622:20: note: in definition of
macro 'RT_CONSTANT_EX'
((zval*)(((char*)(base)) + (node).constant))
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:426:28: note: in
expansion of macro 'RT_CONSTANT'
opline->op2.constant = RT_CONSTANT(opline, opline->op2) - literals;
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:479:29: error:
'zend_arg_info' has no member named 'type'
if (ZEND_TYPE_IS_CLASS(p->type)) {
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:480:51: error:
'zend_arg_info' has no member named 'type'
zend_bool allow_null = ZEND_TYPE_ALLOW_NULL(p->type);
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:481:47: error:
'zend_arg_info' has no member named 'type'
zend_string *type_name = ZEND_TYPE_NAME(p->type);
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:484:7: error:
'zend_arg_info' has no member named 'type'
p->type =
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:485:27: error:
'zend_type' undeclared (first use in this function)
(Z_UL(1) << (sizeof(zend_type)*8-1)) | /* type is class */
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:487:18: error:
expected ';' before 'type_name'
(zend_type)type_name;
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c: In function
'zend_file_cache_unserialize_ast':
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:908:49: error:
'ZEND_AST_CONSTANT' undeclared (first use in this function)
if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c: In function
'zend_file_cache_unserialize_op_array':
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1024:64: error: macro
"ZEND_PASS_TWO_UPDATE_CONSTANT" passed 3 arguments, but takes just 2
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, opline->op1);
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1024:5: error:
'ZEND_PASS_TWO_UPDATE_CONSTANT' undeclared (first use in this function)
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, opline->op1);
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1027:64: error: macro
"ZEND_PASS_TWO_UPDATE_CONSTANT" passed 3 arguments, but takes just 2
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, opline->op2);
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1079:10: error:
'zend_arg_info' has no member named 'type'
if (p->type & (Z_UL(1) << (sizeof(zend_type)*8-1))) { /* type is class */
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1079:39: error:
'zend_type' undeclared (first use in this function)
if (p->type & (Z_UL(1) << (sizeof(zend_type)*8-1))) { /* type is class */
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1080:31: error:
'zend_arg_info' has no member named 'type'
zend_bool allow_null = (p->type & (Z_UL(1) << (sizeof(zend_type)*8-2))) != 0; /*
type allow null */
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1081:47: error:
'zend_arg_info' has no member named 'type'
zend_string *type_name = (zend_string*)(p->type & ~(((Z_UL(1) <<
(sizeof(zend_type)*8-1))) | ((Z_UL(1) << (sizeof(zend_type)*8-2)))));
^
/usr/local/directadmin/custombuild/php-7.1.13RC1/ext/opcache/zend_file_cache.c:1084:7: error:
'zend_arg_info' has no member named 'type'
p->type = ZEND_TYPE_ENCODE_CLASS(type_name, allow_null);
^
make: *** [ext/opcache/zend_file_cache.lo] Error 1
make: *** Waiting for unfinished jobs....
------------------------------------------------------------------------
[2017-12-19 11:17:44] post at minhost dot no
Thank you both, @nikic and @dmitry! I want to test the patch, however can I apply the patch from
@dmitry directly into PHP 7.1.12? Or is it needed to use the 7.1.13 branch from https://github.com/php/php-src/tree/PHP-7.1.13
?
------------------------------------------------------------------------
[2017-12-18 18:10:22] dmitry@php.net
I committed a fix into the master branch https://github.com/php/php-src/commit/ce4fb228e033ef896517aea3d01eb8d9ac055366
Could you please verify, if this completely fixes the problem.
Then, I'll backport it into PHP-7.*
------------------------------------------------------------------------
[2017-12-17 21:19:06] nikic@php.net
@dmitry: Can you please take a look at this issue? I'm not sure what the best way to fix this
is. Can we just zend_shared_alloc() the string in case the accel_new_interned_string() fails?
An easy way to reproduce this is to enable the file cache, cache some files with
opcache.interned_strings_buffer=8 and then load them using opcache.interned_strings_buffer=0.
------------------------------------------------------------------------
[2017-12-17 21:11:44] nikic@php.net
The issue (presumably) is https://github.com/php/php-src/blob/master/ext/opcache/zend_file_cache.c#L229.
If the script in the file cache uses an interned string, the string is not already in the interned
string buffer, and the interned string buffer has run full, this simply directly returns the string
from the string segment of the cached script. However, the string segment will be freed in https://github.com/php/php-src/blob/master/ext/opcache/zend_file_cache.c#L1467.
The reason why you are only seeing this issue now is due to https://github.com/php/php-src/commit/d82805f097564558d94e3062e87b17d6ccae893f
and the fact that you use revalidate_path=1. Prior to this fix, if revalidate_path=1 opcache
accidentally did not use the interned string buffer for most things, which is why the file cache
also did not contain interned strings.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=75579
--
Edit this bug report at https://bugs.php.net/bug.php?id=75579&edit=1