-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Handle reallocated root buffer during GC destroy phase (v2) #4935
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
Handle reallocated root buffer during GC destroy phase (v2) #4935
Conversation
|
Zend/zend_gc.c
Outdated
@@ -1555,6 +1555,8 @@ ZEND_API int zend_gc_collect_cycles(void) | |||
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); | |||
GC_ADDREF(obj); | |||
obj->handlers->free_obj(obj); | |||
current = GC_IDX2PTR(idx); // bug #78811: free_obj() can cause the root buffer to be reallocated. | |||
obj = (zend_object*)GC_GET_PTR(current->ref); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, reassigning obj
might be the unnecessary part.
current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset);
- The left hand assignment was to the pointer current
, which is the expression that should be recomputed.
The fix continues to work for me
a9a1f40
to
1a90ab9
Compare
@nikic please take a look. |
I agree that it would be better to fix this by moving it above the call, rather than recomputing the pointer. I don't think this is needed for 7.3 though, as GC is still protected during "destroy value" phase on 7.3, this only changed in 7.4. |
We no longer protect GC during the destroy phase, so we need to deal with buffer reallocation. Note that the implementation of spl_SplObjectStorage_free_storage will call the destructor of SplObjectStorage, and free the instance properties, which I think is what caused the root buffer to be reallocated. (`current` is a pointer for an index within the root buffer?) This fixes bug #78811 for me.
1a90ab9
to
f205cf3
Compare
Done and changed the target branch to PHP-7.4. The fix still works when applied to |
Zend/zend_gc.c
Outdated
@@ -1561,6 +1561,8 @@ ZEND_API int zend_gc_collect_cycles(void) | |||
EG(objects_store).object_buckets[obj->handle] = SET_OBJ_INVALID(obj); | |||
GC_TYPE_INFO(obj) = IS_NULL | | |||
(GC_TYPE_INFO(obj) & ~GC_TYPE_MASK); | |||
/* Modify current before calling free_obj(bug #78811: free_obj() can cause the root buffer (with current) to be reallocated.) */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing whitespace before (.
Squashed and merged - the latest commit was just a comment spacing change |
We no longer protect GC during the destroy phase, so we need to deal with buffer reallocation. Note that the implementation of spl_SplObjectStorage_free_storage will call the destructor of SplObjectStorage, and free the instance properties, which I think is what caused the root buffer to be reallocated. (`current` is a pointer for an index within the root buffer?) This fixes bug #78811 for me. Closes GH-4935
I forgot that the target branch was changed to PHP-7.4. Fixed. |
We no longer protect GC during the destroy phase, so we need to
deal with buffer reallocation.
Note that the implementation of spl_SplObjectStorage_free_storage
will call the destructor of SplObjectStorage, and free the instance properties,
which I think is what caused the root buffer to be reallocated.
This fixes bug #78811 for me.
I needed both of the lines - the crash still happened before
current = GC_IDX2PTR(idx)
was added (gdb said that current->ptr was invalid memory)The build failure is spurious