[php-src] Issue #24185: PHP 8.5+ Windows ZTS: random access violations with OPcache JIT in multi-process setups

From: Date: Thu, 08 Oct 2026 01:58:03 +0000
Subject: [php-src] Issue #24185: PHP 8.5+ Windows ZTS: random access violations with OPcache JIT in multi-process setups
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-252938@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/24185 Author: alvin0319 ### Description Reproduce code: child.ini (same directory): ```ini opcache.enable=1 opcache.enable_cli=1 opcache.protect_memory=1 opcache.jit=1205 opcache.jit_buffer_size=128M ``` repro-parent.php (parent should also use child.ini): ```php <?php declare(strict_types=1); $suppress = ($argv[1] ?? 'false') === 'true'; $runs = (int) ($argv[2] ?? 10); const ACCESS_VIOLATION = -1073741819; $crashes = 0; for($i = 1; $i <= $runs; $i++){ $cmd = 'start "" /b /wait ' . PHP_BINARY . ' -n -c ' . __DIR__ . '\child.ini ' . __DIR__ . '\repro-child.php & exit'; $proc = proc_open($cmd, [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, __DIR__, getenv(), ['suppress_errors' => $suppress]); fclose($pipes[0]); $out = stream_get_contents($pipes[1]); fclose($pipes[1]); fclose($pipes[2]); $code = proc_close($proc); if($code === ACCESS_VIOLATION){ $crashes++; } echo "run $i: exit $code, output: " . trim($out) . "\n"; } echo "suppress_errors=" . var_export($suppress, true) . ": $crashes / $runs runs crashed\n"; exit($crashes > 0 ? 1 : 0); ``` repro-child.php (must use child.ini): ```php <?php declare(strict_types=1); function fixedArrayRead(SplFixedArray $array, int $index) : mixed{ return $array->offsetGet($index); } function makeDate(string $value) : DateTimeImmutable{ return new DateTimeImmutable($value); } function iteratorSeek(ArrayIterator $iterator, int $position) : void{ $iterator->seek($position); } $caught = 0; $array = new SplFixedArray(1); $iterator = new ArrayIterator([1]); for($i = 0; $i < 10; $i++){ try{ fixedArrayRead($array, 5); }catch(RuntimeException $e){ $caught++; } try{ makeDate('not a date'); }catch(Exception $e){ $caught++; } try{ iteratorSeek($iterator, 5); }catch(OutOfBoundsException $e){ $caught++; } } echo "caught $caught\n"; ``` Run: ``` php -n -c child.ini repro-parent.php true 50 ``` In theory, the child script's expected output should be caught 30 because exceptions should be caught by try-catch. But in PHP 8.5+ (ZTS, OPcache JIT enabled), this causes ACCESS_VIOLATION for some reason with OPcache JIT enabled. Tests with GitHub actions runner: [action log](https://github.com/alvin0319/php-jit-bug-testing/actions/runs/37713764335) Full code snippets can be found on [this repo](https://github.com/alvin0319/php-jit-bug-testing) ### PHP Version ```plain PHP 8.5.11 (cli) (built: Sep 22 2026 13:50:46) (ZTS Visual C++ 2022 x64) Copyright (c) The PHP Group Built by The PHP Group Zend Engine v4.5.11, Copyright (c) Zend Technologies with Zend OPcache v8.5.11, Copyright (c), by Zend Technologies PHP 8.6.0RC3 (cli) (built: Oct 6 2026 17:20:27) (ZTS Visual C++ 2026 x64) Copyright © The PHP Group and Contributors Built by The PHP Group Zend Engine v4.6.0RC3, Copyright © Zend by Perforce with Zend OPcache v8.6.0RC3, Copyright ©, by Zend by Perforce ``` ### Operating System Windows 10 Pro 22H2 (10.0.19045), Windows Server 2025 (windows-2025-vs2026 runner image)

« previous php.bugs (#252938) next »