After preloading has executed, the executor globals for class_table and
function_table are still referring to the values during preloading.
If no request happens after that then these values will remain dangling
pointers. If then the -v option on CLI or -h option (and possibly
others) on CGI is provided, there is a double free.
Fix it by nulling the pointers explicitly after preloading has finished
to fix it for all SAPIs.
Closes GH-12311.
This test triggers narrowing for two ops: first ZEND_ADD_ARRAY_ELEMENT,
and then ZEND_ASSIGN.
The type inference happens in the following order:
1) The ZEND_ADD_ARRAY_ELEMENT infers type 0x40e04080 (packed flag is set),
arr_type=0 at this point because it hasn't been set by ZEND_INIT_ARRAY yet.
2) The ZEND_INIT_ARRAY infers type 0x40804080
3) The ZEND_ADD_ARRAY_ELEMENT infers type 0x40e04080, arr_type=0x40804080,
which does not have the packed flag set while the existing result of
ZEND_ADD_ARRAY_ELEMENT has the packed flag set.
This seems to occur because of the phi node introduced by the while
loop. If I remove the loop the problem goes away.
As Arnaud noted, this seems to be caused by a too wide type inference
for arr_type==0. We should keep the invariant that if x>=y then
key_type(x) >= key_type(y).
If we write the possible results down in a table we get:
```
arr_type resulting key type
--------------- --------------------------------------------------------------------------
HASH_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH
PACKED_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
HASH || PACKED -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
0 -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
```
As we can see, `HASH_ONLY > 0` but
`MAY_BE_ARRAY_NUMERIC_HASH < MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED`,
which violates the invariant.
Instead if we modify the zero case to have MAY_BE_ARRAY_NUMERIC_HASH instead,
we get the following table which satisfies the invariant.
```
arr_type resulting key type
--------------- --------------------------------------------------------------------------
HASH_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH
PACKED_ONLY -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
HASH || PACKED -> MAY_BE_ARRAY_NUMERIC_HASH | MAY_BE_ARRAY_PACKED (== MAY_BE_ARRAY_KEY_LONG)
0 -> MAY_BE_ARRAY_NUMERIC_HASH
```
Broke in 1ffbb73.
Closes GH-10294.
There are a couple of oddities.
1) The interned strings buffer comprises the whole hashtable
datastructure.
Therefore, it seems that the interned strings buffer size is the size of
only said table. However, in the current code it also includes the size
of the zend_accel_shared_globals.
2) ZCSG(interned_strings).end is computed starting from the accelerator
globals struct itself. I would expect it to start from the part where
the interned strings table starts.
3) When computing the used size, it is done using
ZCSG(interned_strings).end - ZCSG(interned_strings).start. However,
this does not include the uin32_t slots array because
ZCSG(interned_strings).start pointers after that array.
This patch corrrects these 3 points.
Closes GH-11717.
Not sure if this is possible to hit in practice, zend_accel_error_noreturn
doesn't return so the unlock isn't called. Other callsites that use both
zend_accel_error_noreturn and zend_shared_alloc_unlock first perform the
unlocking.
Closes GH-11718.
If opcache isn't loaded, then opcache_invalidate() will fail.
Reproducible when you compile PHP without opcache, or run PHP without
opcache loaded, and try to run this test.
Closes GH-11378.
I chose to check for the value of lock_file instead of checking the
file_cache_only, because it is probably a little bit faster and we're
going to access the lock_file variable anyway. It's also more generic.
Closes GH-11341.
The break is outside the if, so if it succeeds or not this will always
stop after the first loop iteration instead of trying more allocators if
the first one fails.
Closes GH-11306.
The block optimizer pass allows the use of sources of the preceding
block if the block is a follower and not a target. This causes issues
when trying to remove FREE instructions: if the source is not in the
block of the FREE, then the FREE and source are still removed. Therefore
the other successor blocks, which must consume or FREE the temporary,
will still contain the FREE opline. This opline will now refer to a
temporary that doesn't exist anymore, which most of the time results in
a crash. For these kind of non-local scenarios, we'll let the SSA
based optimizations handle those cases.
Closes GH-11251.
There is a typo which causes the AND and OR range inference to infer a
wider range than necessary. Fix this typo. There are many ranges for
which the inference is too wide, I just picked one for AND and one for
OR that I found through symbolic execution.
In this example test, the previous range inferred for test_or was [-27..-1]
instead of [-20..-1].
And the previous range inferred for test_and was [-32..-25]
instead of [-28..-25].
Closes GH-11170.
Commit a21195650e fixed a leak by adding a TSRM destructor for the
JIT globals in ZTS mode. In case the main thread shuts down the TSRM, it
will call all the destructors. The JIT globals destructor will be
invoked, but will always access the main thread globals using JIT_G.
This means that instead of freeing the JIT globals in the different
threads, the one in the main thread is freed repeatedly over and over,
crashing PHP. Fix it by always passing the pointer instead of relying on
JIT_G.
Closes GH-10835.
Fixes GH-10801
Named arguments are not supported by the constant evaluation routine, in
the sense that they are ignored. This causes two issues:
- It causes a crash because not all oplines belonging to the call are
removed, which results in SEND_VA{L,R} which should've been removed.
- It causes semantic issues (demonstrated in the test case).
This case never worked anyway, leading to crashes or incorrect behaviour,
so just prevent CTE of calls with named parameters for now.
We can choose to support it later, but introducing support for this in
a stable branch seems too dangerous.
This patch does not change the removal of SEND_* opcodes in remove_call
because the crash bug can't be triggered anymore with this patch as
there are no named parameters anymore and no variadic CTE functions
exist.
Closes GH-10811.
Disable opcache.consistency_checks.
This feature does not work right now and leads to memory leaks and other
problems. For analysis and discussion see GH-8065. In GH-10624 it was
decided to disable the feature to prevent problems for end users.
If end users which to get some consistency guarantees, they can rely on
opcache.protect_memory.
Closes GH-10798.
Remove capstone include folder.
For most of the supported systems it worked fine somehow despite
the pkg-config --cflags, but is always include it even on Linux.
Closes GH-10732.
test failre introduced by 44e5c04e55
This ASSERT-ion path was never reached becuase of the bug fixed by
44e5c04e55. It's possible in case of
circular class dependencies that may resolved by __autoload().
Unfortunately these circular dependencies can't be stored in the
inheritace cahce.
Commit a21195650e added a TSRM destructor, but that destructor
will get called by tsrm_shutdown(), which is after opcache.so has
already been unloaded, resulting in a shutdown crash, e.g.:
#0 0x00007fad01737500 in ?? ()
#1 0x000055ac54e723c4 in tsrm_shutdown () at TSRM/TSRM.c:194
#2 0x000055ac54c42180 in main (argc=80, argv=0x55ac57bc14d0) at sapi/cli/php_cli.c:1388
By calling ts_free_id() before opcache.so gets unloaded, we can easily
fix this crash bug.
* ext/opcache/zend_jit: cast function to fix -Wincompatible-pointer-types
Regression by commit a21195650e
* TSRM/win32: fix ts_allocate_dtor cast
The dtor was casted to ts_allocate_ctor; luckily, ts_allocate_dtor and
ts_allocate_ctor just happen to be the same type.