This fixes an edge case causing the GC to be triggered repeatedly.
Destructors might add potential garbage to the buffer, so it may happen that num_root it higher than gc_threshold after collection, thus triggering a GC run almost immediately. This can happen by touching enough objects in a destructor, e.g. by iterating over an array. If this happens again in the new run, and the threshold is not updated, the GC may be triggered again.
The edge case requires specific conditions to be triggered and it must happen rarely in practice:
* At least GC_THRESHOLD_TRIGGER (100) objects must be collected during each run for the threshold to not be updated
* At least GC_G(gc_threshold) (initially 10k) objects must be touched (decref'ed to n>0) by any destructor during each run to fill the buffer
The fix is to increase the threshold if GC_G(num_roots) >= GC_G(gc_threshold) after GC. The threshold eventually reaches a point at which the second condition is not met anymore.
The included tests trigger more than 200 GC runs before the fix, and 2 after the fix (dtors always trigger a second run).
A related issue is that zend_gc_check_root_tmpvars() may add potential garbage before the threshold is adjusted, which may trigger GC and exhaust the stack. This is fixed by setting GC_G(active)=1 around zend_gc_check_root_tmpvars().
`if (fpm_shm_size - size > 0)` will be rewritten by the compiler as this: `if (fpm_shm_size != size)`, which is undesirable. The reason this happens is that both variables are size_t, so subtracting them cannot be negative. The only way it can be not > 0, is if they're equal because the result will then be 0. This means that the else branch won't work properly. E.g. if `fpm_shm_size == 50` and `size == 51`, then `fpm_shm_size` will wraparound instead of becoming zero.
To showcase that the compiler actually does this, take a look at this
isolated case: https://godbolt.org/z/azobdWcrY. Here we can see the
usage of the compare instruction + cmove, so the "then" branch
is only done if the variables are equal.
Symfony relies on finding the exception handler in the handler stack. There's
currently no clean API to find it, so they pop all the handlers, and push them
again once the stack is empty. This PR attempts to minimize the BC break by
pushing the current handler onto the stack and clearing the current handler, and
restoring it once it has finished. This is essentially equivalent to
set_exception_handler(null) and restore_exception_handler().
restore_exception_handler() however is only called if the exception handler is
still unset. If the handler has pushed a new handler in the meantime, we assume
it knows what it's doing.
Fixes GH-13446
Closes GH-13686
Inherited methods regardless of source must share the original runtime cache. Traits were missed.
This adds ZEND_ACC_TRAIT_CLONE to internal functions as well to allow easy distinction of these.
Moving the minimum base of the shared opcache memory to the second huge page to avoid a possible 0x0 base, which may cause all sorts of segfaults.
This is not a problem on most systems which have a mmap_min_addr which is non-zero, but e.g. WSL1 doesn't have a minimum mapping address.
In commit 85e5635a, a feature test for the various libgd image formats
was added. That test however erroneously omits the GDLIB_CFLAGS (from
pkg-config) during compilation. This can lead to build failures and
therefore false negatives from the test.
Here, we add $GDLIB_CFLAGS to $CFLAGS for the duration of the test.
Closes GH-12019
autoconf/libtool generating code to test features missed `void` for
C calls prototypes w/o arguments.
Note that specific changes related to libtool have to be upstreamed.
Co-authored-by: Peter Kokot <petk@php.net>
close GH-13732
Regressed in 6fbf81c.
There is a missing error check on spl_filesystem_file_read_line(), which
means that if the line could not be read (e.g. because we're at the end
of the file), it will not set intern->u.file.current_line, which will
cause a NULL pointer deref later on.
Fix it by adding a check, and reintroducing the silent flag partially to
be able to throw an exception like it did in the past.
Closes GH-13692.
This is not just an issue due to missing initialization since moving the state
struct directly into the module globals. In earlier versions changing the mode
to `MT_RAND_PHP` within a single request would also affect the mode for
subsequent requests.
Original commit message follows:
This is a follow-up fix for GH-13579. The issue was detected in the nightly
MSAN build.
(cherry picked from commit bf0abd1629)