-
Notifications
You must be signed in to change notification settings - Fork 7.9k
CoW involved sometimes /w opcache #18600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I don't understand what is being tested here. |
The code is used to obtain "id of a variable" to be later used to prevent recursion when dumping an array. The code in the repro is minimal code needed to reproduce it without much meaning. I know there is no guarantee from the language that reference id will not change once there is no reference active. But so far I understand the design the reference id is computed as a hash of zval ptr. This is shown in https://3v4l.org/710ps. So the issue reported here is what opcache does to the variable so that the zval is copied and if that can be avoided. Maybe something can be improved. |
The reference is not just "inactive", the reference is gone, it is freed. In your example, the new reference by chance just happens to live in the same memory where the previous reference lived. Essentially, the buffered |
Why the repro is fixed by atk4/core@12e4abc this change? |
@mvorisek It's hard to tell when you're relying on memory allocations being placed in specific slots. The point remains: If your allocation is freed, the value returned from |
Here is the usecase I need to solve:
repro: https://3v4l.org/6KKQu Currently, I use:
to get a variable reference id. I understand it can return the same result if variable, more precisely zval, is released and allocated again. This implies me these questions: How can I get a reference id from a any variable or an object property?Currently the only function that can return reference id I am aware of is the Shouldn't there be also a If I use the However. What is a reference internally and what is the reference idIf I am right, the reference id (in sense of A zval is allocated on the first assign. The situation when zval is copied is when it is to be modified and has refcount>1. Changing variable to be a reference, or a reference passed by a value implies modification. When the refcount=1, no zval copy is done as not needed. So if this is true, the So in opcache (or possibly xdebug), there is something that increases refcount of the passed variable causing the zval to be split (copied). And hence this issue as refcount should not be increased with opcache more than without, as it has side effects. |
You can't get the id for any variable. You can get it for properties like this: https://3v4l.org/DXVnX There seem to be some misunderstandings in your explanation. Zvals are not separate from references. Zvals can either live on the stack or in the zend_reference allocation. getId() always refers to the zend_reference pointer, stack zvals can never be referenced. Nor can array elements, they are volatile and may be moved. |
Uh oh!
There was an error while loading. Please reload this page.
Description
The following code:
minimal repro repo: https://github.com/atk4/core/tree/debug_ref_change_with_opcache_and_coverage
It contains 2 files.
.github/workflows/test-unit.yml
- working CI on pushrepro.php
Resulted in this output:
But I expected this output instead:
no output - references are the same
My observations when minimalizing the reproducer:
The repro contains simple
repro.php
reproduced.When run using the CI, it fails with the unexpected result under these conditions:
The CoW, ie. references updated, is involved in most runs, but not always. In the CI, I run the repro 10x and with >90% probablity at least one of PHP 8.2/8.3/8.4 job fails.
I am not sure if xdebug needs to be installed, but it helps to reproduce the issue more frequently.
Opcache seems however always needed.
Disabled GC has no impact.
Also it seems the
Closure::bind
in the repro is needed to reproduce.Please confirm you can reproduce this issue on your side.
PHP Version
Operating System
Ubuntu
The text was updated successfully, but these errors were encountered: