From b037fe5bd1d8289dde5f922908c06437d7027d8e Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Tue, 19 Nov 2019 19:12:56 -0500 Subject: [PATCH] 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 --- Zend/zend_gc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index c36f4e7ced..7cecd53410 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -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.) */ + 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); @@ -1569,7 +1571,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; -- 2.40.0