Bug #70656 [Com]: require() statement broken after opcache_reset() or a few hours of use

From: Date: Sun, 01 Nov 2015 04:42:38 +0000
Subject: Bug #70656 [Com]: require() statement broken after opcache_reset() or a few hours of use
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-196955@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70656&edit=1 ID: 70656 Comment by: tony dot levi at blackboard dot com Reported by: p at wspnr dot com Summary: require() statement broken after opcache_reset() or a few hours of use Status: Assigned Type: Bug Package: opcache Operating System: Debian (x86_64 and i686) PHP Version: 7.0Git-2015-10-07 (Git) Assigned To: laruence Block user comment: N Private report: N New Comment: Confirming that patch solves it for me too. Previous Comments: ------------------------------------------------------------------------ [2015-11-01 03:53:35] p at wspnr dot com Applied patch and recompiled. The bug seems to be resolved. ------------------------------------------------------------------------ [2015-11-01 03:30:36] laruence@php.net actually, it's intentional only copy Z_STRLEN, please verify this fix: diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index eaadac6..18862b3 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -249,24 +249,27 @@ static void accel_interned_strings_restore_state(void) uint nIndex; Bucket *p; - ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top); - while (idx > 0) { - idx--; - p = ZCSG(interned_strings).arData + idx; - if ((char*)p->key < ZCSG(interned_strings_top)) break; - ZCSG(interned_strings).nNumUsed--; - ZCSG(interned_strings).nNumOfElements--; - - nIndex = p->h | ZCSG(interned_strings).nTableMask; - if (HT_HASH(&ZCSG(interned_strings), nIndex) == HT_IDX_TO_HASH(idx)) { - HT_HASH(&ZCSG(interned_strings), nIndex) = Z_NEXT(p->val); - } else { - uint32_t prev = HT_HASH(&ZCSG(interned_strings), nIndex); - while (Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) != idx) { - prev = Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val); - } - Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) = Z_NEXT(p->val); - } + if (EXPECTED(ZCSG(interned_strings_top) > ZCSG(interned_strings_saved_top))) { + memset(ZCSG(interned_strings_saved_top),0, ZCSG(interned_strings_top) - ZCSG(interned_strings_saved_top)); + ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top); + while (idx > 0) { + idx--; + p = ZCSG(interned_strings).arData + idx; + if ((char*)p->key < ZCSG(interned_strings_top)) break; + ZCSG(interned_strings).nNumUsed--; + ZCSG(interned_strings).nNumOfElements--; + + nIndex = p->h | ZCSG(interned_strings).nTableMask; + if (HT_HASH(&ZCSG(interned_strings), nIndex) == HT_IDX_TO_HASH(idx)) { + HT_HASH(&ZCSG(interned_strings), nIndex) = Z_NEXT(p->val); + } else { + uint32_t prev = HT_HASH(&ZCSG(interned_strings), nIndex); + while (Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) != idx) { + prev = Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val); + } + Z_NEXT(HT_HASH_TO_BUCKET(&ZCSG(interned_strings), prev)->val) = Z_NEXT(p->val); + } + } } } ------------------------------------------------------------------------ [2015-10-31 17:49:34] kalle@php.net Hey Xinchen, can you confirm this fix is proper or clarify the behavior? Thanks ------------------------------------------------------------------------ [2015-10-31 08:09:31] tony dot levi at blackboard dot com I can confirm that workaround and proposed fix solve the issue for me. It looks like the right solution - based on pattern elsewhere - but I'm not an expert either. ------------------------------------------------------------------------ [2015-10-30 17:45:43] p at wspnr dot com I spent some time today tracing this bug as it is preventing our migration to PHP 7. The bug is caused by the opcache interned strings functionality. A simple workaround is to set opcache.interned_strings_buffer = 0 in php.ini. Looking at the code, I believe that the bug might be caused by this [0] call to memcpy(). Changing this to memcpy(ZSTR_VAL(p->key), ZSTR_VAL(str), ZSTR_LEN(str) + 1); has made the issue go away. However I am not familiar enough with opcache to determine whether this is an acceptable change. [0] http://lxr.php.net/xref/PHP_MASTER/ext/opcache/ZendAccelerator.c#374 ------------------------------------------------------------------------ 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=70656 -- Edit this bug report at https://bugs.php.net/bug.php?id=70656&edit=1

« previous php.bugs (#196955) next »