Commit 430f1be
committed
Fix GH-8739: OPcache restart corrupts SHM in threaded SAPIs (ZTS)
Before executing a scheduled restart (OOM, hash overflow or
opcache_reset()), accel_is_inactive() checks that no request is still
reading shared memory. On POSIX this check is implemented with fcntl()
record locks: readers take an F_RDLCK in accel_activate_add() and the
restarting thread probes for it with F_GETLK.
POSIX record locks are per-process: a process never conflicts with its
own locks. In threaded SAPIs (FrankenPHP, mod_php with a threaded MPM),
all in-flight requests are threads of one process, so F_GETLK never
reports a conflict and accel_is_inactive() always returns true. The
restart then runs zend_accel_hash_clean() and
accel_interned_strings_restore_state() while other threads execute
op_arrays and hold interned string pointers in the wiped memory,
corrupting the heap ("zend_mm_heap corrupted", SIGSEGV/SIGABRT).
Fix it the way ZEND_WIN32 already solved the same problem for threaded
SAPIs on Windows: track in-flight requests with an atomic counter in
SHM. Requests register in RINIT (only while the accelerator is enabled,
so registrations stop as soon as a restart is pending and the counter
drains within the duration of the longest in-flight request) and
deregister in accel_post_deactivate(). accel_is_inactive() refuses to
restart while the counter is non-zero.
The counter is only compiled in for ZTS non-Windows builds; NTS
process-based SAPIs (php-fpm, mod_php prefork) keep using fcntl()
locks, whose kernel-side cleanup on process death they rely on.
Verified on a production Symfony workload under FrankenPHP (256
threads, ~120 concurrent requests): repeated opcache_reset() calls and
wasted-memory-exhaustion restarts, both previously crashing within
seconds, now complete safely after draining readers.1 parent 61a1b9a commit 430f1be
3 files changed
Lines changed: 68 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
65 | 68 | | |
66 | 69 | | |
67 | 70 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
402 | 402 | | |
403 | 403 | | |
404 | 404 | | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
405 | 437 | | |
406 | 438 | | |
407 | 439 | | |
| |||
894 | 926 | | |
895 | 927 | | |
896 | 928 | | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
897 | 936 | | |
898 | 937 | | |
899 | 938 | | |
| |||
2742 | 2781 | | |
2743 | 2782 | | |
2744 | 2783 | | |
| 2784 | + | |
| 2785 | + | |
| 2786 | + | |
| 2787 | + | |
| 2788 | + | |
| 2789 | + | |
| 2790 | + | |
| 2791 | + | |
| 2792 | + | |
| 2793 | + | |
| 2794 | + | |
2745 | 2795 | | |
2746 | 2796 | | |
2747 | 2797 | | |
| |||
2793 | 2843 | | |
2794 | 2844 | | |
2795 | 2845 | | |
| 2846 | + | |
| 2847 | + | |
| 2848 | + | |
| 2849 | + | |
| 2850 | + | |
| 2851 | + | |
| 2852 | + | |
| 2853 | + | |
2796 | 2854 | | |
2797 | 2855 | | |
2798 | 2856 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
197 | 197 | | |
198 | 198 | | |
199 | 199 | | |
| 200 | + | |
200 | 201 | | |
201 | 202 | | |
202 | 203 | | |
| |||
267 | 268 | | |
268 | 269 | | |
269 | 270 | | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
270 | 277 | | |
271 | 278 | | |
272 | 279 | | |
| |||
0 commit comments