summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyson Andre <tysonandre775@hotmail.com>2019-11-19 19:12:56 -0500
committerTyson Andre <tysonandre775@hotmail.com>2019-11-23 10:24:48 -0500
commit500ba8b2b86802c130694026c5e821806ffbd3c9 (patch)
treeba50e83f536e08658295e7fdf5cbfcd2f8d8e78c
parente7e15450ef68c354b43cd027b1407942986dd171 (diff)
downloadphp-git-500ba8b2b86802c130694026c5e821806ffbd3c9.tar.gz
Handle reallocated root buffer during GC destroy phase (v2)
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
-rw-r--r--Zend/zend_gc.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index a3c3691be0..30698f4484 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -1551,6 +1551,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.) */
+ current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset);
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
GC_ADDREF(obj);
@@ -1559,7 +1561,6 @@ ZEND_API int zend_gc_collect_cycles(void)
}
ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(obj->handle);
- current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset);
} else if (GC_TYPE(p) == IS_ARRAY) {
zend_array *arr = (zend_array*)p;