summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-08-28 17:04:55 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-08-28 17:04:55 +0200
commit6323c13e74eb63cf03e11a36c68f4fdf2077872a (patch)
tree14ac20ccd7138d2d7e3bb6b0b4ef632d710f600e
parentafb69b6f2d4872d6b916c10d7d394ca304481865 (diff)
parentc45f19590c4d442c0ecf5a3b55cd0fb928243e6a (diff)
downloadphp-git-6323c13e74eb63cf03e11a36c68f4fdf2077872a.tar.gz
Merge branch 'PHP-7.4'
-rw-r--r--Zend/zend_execute_API.c31
-rw-r--r--Zend/zend_objects_API.c5
2 files changed, 17 insertions, 19 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 1465e9afd3..ac95aa5cc3 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -316,6 +316,21 @@ void shutdown_executor(void) /* {{{ */
}
} ZEND_HASH_FOREACH_END();
+ /* Also release error and exception handlers, which may hold objects. */
+ if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
+ zval_ptr_dtor(&EG(user_error_handler));
+ ZVAL_UNDEF(&EG(user_error_handler));
+ }
+
+ if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
+ zval_ptr_dtor(&EG(user_exception_handler));
+ ZVAL_UNDEF(&EG(user_exception_handler));
+ }
+
+ zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
+ zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
+ zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
+
#if ZEND_DEBUG
if (gc_enabled() && !CG(unclean_shutdown)) {
gc_collect_cycles();
@@ -342,22 +357,6 @@ void shutdown_executor(void) /* {{{ */
zend_hash_discard(EG(class_table), EG(persistent_classes_count));
zend_cleanup_internal_classes();
} else {
- /* remove error handlers before destroying classes and functions,
- * so that if handler used some class, crash would not happen */
- if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
- zval_ptr_dtor(&EG(user_error_handler));
- ZVAL_UNDEF(&EG(user_error_handler));
- }
-
- if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
- zval_ptr_dtor(&EG(user_exception_handler));
- ZVAL_UNDEF(&EG(user_exception_handler));
- }
-
- zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
- zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
- zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_PTR_DTOR, 1);
-
zend_vm_stack_destroy();
if (EG(full_tables_cleanup)) {
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c
index 7c5d44a502..80359b5e1e 100644
--- a/Zend/zend_objects_API.c
+++ b/Zend/zend_objects_API.c
@@ -87,7 +87,8 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_
return;
}
- /* Free object contents, but don't free objects themselves, so they show up as leaks */
+ /* Free object contents, but don't free objects themselves, so they show up as leaks.
+ * Also add a ref to all objects, so the object can't be freed by something else later. */
end = objects->object_buckets + 1;
obj_ptr = objects->object_buckets + objects->top;
@@ -101,7 +102,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_
if (obj->handlers->free_obj != zend_object_std_dtor) {
GC_ADDREF(obj);
obj->handlers->free_obj(obj);
- GC_DELREF(obj);
}
}
}
@@ -115,7 +115,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
GC_ADDREF(obj);
obj->handlers->free_obj(obj);
- GC_DELREF(obj);
}
}
} while (obj_ptr != end);