Bug #76832 [NEW]: ZendOPcache.MemoryBase periodically deleted by the OS
| From: | webmaster_20180824 at cubiclesoft dot com | Date: | Sat, 01 Sep 2018 06:47:05 +0000 |
| Subject: | Bug #76832 [NEW]: ZendOPcache.MemoryBase periodically deleted by the OS | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-216839@lists.php.net to get a copy of this message | ||
From: webmaster_20180824 at cubiclesoft dot com
Operating system: Windows
PHP version: 7.2.9
Package: opcache
Bug Type: Bug
Bug description:ZendOPcache.MemoryBase periodically deleted by the OS
Description:
------------
My most recent adventure with PHP started with the following seemingly
innocuous message being emitted:
Fatal Error Unable to open base address file
There is exactly one place where this message is emitted in
'ext\opcache\shared_alloc_win32.c' in the zend_shared_alloc_reattach()
function. The function attempts to open a temporary file as read only.
If it fails to open the file, the message above is the emitted error and
ALLOC_FAILURE is returned to the caller.
There is only one caller of the zend_shared_alloc_reattach() function,
which is the create_segments() function. The relevant code from
create_segments() is:
zend_shared_alloc_lock_win32();
do {
memfile = OpenFileMapping(FILE_MAP_WRITE, 0,
create_name_with_username(ACCEL_FILEMAP_NAME));
if (memfile == NULL) {
err = GetLastError();
break;
}
ret = zend_shared_alloc_reattach(requested_size, error_in);
if (ret == ALLOC_FAIL_MAPPING) {
err = GetLastError();
/* Mapping failed, wait for mapping object to get freed and retry */
CloseHandle(memfile);
memfile = NULL;
if (++map_retries >= MAX_MAP_RETRIES) {
break;
}
zend_shared_alloc_unlock_win32();
Sleep(1000 * (map_retries + 1));
zend_shared_alloc_lock_win32();
} else {
zend_shared_alloc_unlock_win32();
return ret;
}
} while (1);
So what happens here is that if OpenFileMapping() succeeds (i.e. the
memory map name already exists), then the call to
zend_shared_alloc_reattach() assumes that the temporary file exists.
Unfortunately, Windows 10 Creators Update will periodically delete files
and folders in the user's Temp folder while the OS is running without
bothering to ask the user. I've seen the behavior on brand new, fresh
from shrink-wrapped retail box Win10 installs, which means it is part of
the core product. Regardless, the Temp directory is not a safe place to
store files for more than a few hours on Windows. Once the
'ZendOPcache.MemoryBase@...' file has been deleted, only first fully
shutting down and then restarting the processes running with opcache
will recreate the required file.
Obviously, disabling the opcache altogether will possibly work too.
Update: After monitoring the Temp folder for a solid week with Process
Monitor, I have finally found the culprit: cleanmgr.exe. Once I had an
executable name to look for, I also quickly found the relevant Task
Scheduler task under Microsoft -> Windows -> Disk Cleanup (along with
also finding people online who really, really dislike cleanmgr.exe). It
claims it is just a "Maintenance task used by the system to launch a
silent auto disk cleanup when running low on free disk space." However,
Process Monitor has officially caught it red-handed doing Very Bad
Things(TM) to actively running software on a drive with over 100GB free.
The task is also lacking any triggers, so it looks to me like a very
broken task in Task Scheduler that is found on all Windows 10 OSes. On
the plus side, it looks like files are only deleted after a week of
inactivity, so performing a periodic touch() on the file might be a way
to mitigate the issue. Disabling, altering, or deleting the task in
Task Scheduler will likely only work until the next major Windows Update
cycle. Microsoft has a very bad habit of re-enabling and re-creating
disabled and deleted tasks and system services.
Test script:
---------------
Fastest method to replicate:
Start an Apache + mod_php instance with the opcache enabled.
Delete the 'ZendOPcache.MemoryBase' file from the Temp directory.
Run 'php-cgi.exe' from the command-line.
--
Edit bug report at https://bugs.php.net/bug.php?id=76832&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=76832&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=76832&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=76832&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=76832&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=76832&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=76832&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=76832&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=76832&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=76832&r=support
Expected behavior: https://bugs.php.net/fix.php?id=76832&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=76832&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=76832&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=76832&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=76832&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=76832&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=76832&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=76832&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=76832&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=76832&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=76832&r=mysqlcfg