About virtualprotect() failed 87 the parameter is incorrect
I was investigating the same case.
I tested CMS EFFCORE on the Windows platform (Windows 10 2021 LTSC x64
).
After installing Apache House (httpd-2.4.57-win64-VS17.zip
) and PHP (php-8.2.11-vs16-x64.zip
), I began to include the missing modules to install the system.
I enabled all the required modules and the system installed without problems.
I ran all the tests and they ran successfully.
Then I decided to speed up the system and enabled OPCache + JIT
.
After enabling OPCache + JIT
I started getting a "white screen" and the message virtualprotect() failed 87 the parameter is incorrect
.
After disabling OPCache + JIT
or OPCache
the problem went away.
I was wondering what this error was.
I created a small script and placed it in the test.php
file.
It had the following contents:
$path = 'data.php';
$lines_num = 2000;
if (!file_exists($path)) {
file_put_contents($path, '<?php'."\n", FILE_APPEND);
for ($i = 0; $i < $lines_num; $i++)
file_put_contents($path, '$data['.$i.'] = \'value '.$i."';\n", FILE_APPEND);
file_put_contents($path, 'print \'COUNT: \'.count($data);', FILE_APPEND);
print 'FILE WAS CREATED. RELOAD THIS PAGE';
} else {
include_once($path);
print "\n".'FILE WAS INCLUDED';
}
Next, I ran test.php
from the browser and got a white screen if lines_num
was greater than 2000
and a normal result if less than 2000
.
This is an obvious overflow of some memory segment.
However, the log did not contain any information about the error.
From the console I ran this script with any number of lines_num
and no problems arose.
php -d opcache.jit_debug=1 test.php
php -d opcache.jit_debug=1 data.php
I concluded that the problem is with the Apache + PHP combination as a module.
However, there were no problems under Linux/Unix.
Here is the complete list of links:
- win: Apache + PHP as a module -
JIT problem
- win: IIS + PHP as FastCGI - OK
- win: PHP CLI - OK
- nix: Apache + PHP as a module - OK
- nix: NGINX + PHP as FastCGI - OK
- nix: PHP CLI - OK
I had to disable OPCache in php.ini
via opcache.enable=0
and the problem went away.
In php.ini
you can disable only JIT
via opcache.jit_buffer_size=0
but this setting cannot be changed directly from PHP code.
Changing other opcache.*
settings in php.ini
did not lead to anything.
You can also disable OPCache + JIT
programmatically with the following code:
if (DIRECTORY_SEPARATOR === '\\') {
ini_set('opcache.enable', false);
}
Thank you for your attention, I hope it helped.