summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-03-31 16:09:45 +0400
committerDmitry Stogov <dmitry@zend.com>2014-03-31 16:09:45 +0400
commit47fdb9eae33bdb36d79e6b7eb7afa87fbde9c0ed (patch)
tree9c6cce1ee932c5905dc2025f07f1e8bb0f530934
parent292b8dffc81198ff343354ea2bb26ebd42ca2fa2 (diff)
downloadphp-git-47fdb9eae33bdb36d79e6b7eb7afa87fbde9c0ed.tar.gz
fixed craches at request shutdown and memory leaks
-rw-r--r--Zend/zend_compile.c1
-rw-r--r--Zend/zend_opcode.c3
-rw-r--r--ext/opcache/ZendAccelerator.c8
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.c65
-rw-r--r--ext/opcache/zend_persist.c8
-rw-r--r--ext/opcache/zend_shared_alloc.c1
6 files changed, 57 insertions, 29 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 807ebd508e..9ba40dfc33 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5442,6 +5442,7 @@ void zend_do_declare_property(znode *var_name, const znode *value, zend_uint acc
Z_STR(var_name->u.constant) = zend_new_interned_string(Z_STR(var_name->u.constant) TSRMLS_CC);
zend_declare_property_ex(CG(active_class_entry), Z_STR(var_name->u.constant), &property, access_type, comment TSRMLS_CC);
//??? efree(Z_STRVAL(var_name->u.constant));
+ STR_RELEASE(Z_STR(var_name->u.constant));
}
/* }}} */
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 039c3bbd76..08108d283f 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -115,6 +115,9 @@ ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC)
destroy_op_array((zend_op_array *) function TSRMLS_CC);
break;
case ZEND_INTERNAL_FUNCTION:
+ if (function->common.function_name) {
+ STR_RELEASE(function->common.function_name);
+ }
/* do nothing */
break;
}
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
index 85347be976..5df02c98c8 100644
--- a/ext/opcache/ZendAccelerator.c
+++ b/ext/opcache/ZendAccelerator.c
@@ -2524,9 +2524,14 @@ static void accel_globals_ctor(zend_accel_globals *accel_globals TSRMLS_DC)
zend_accel_copy_internal_functions(TSRMLS_C);
}
+static void accel_globals_internal_func_dtor(zval *zv)
+{
+ free(Z_PTR_P(zv));
+}
+
static void accel_globals_dtor(zend_accel_globals *accel_globals TSRMLS_DC)
{
- accel_globals->function_table.pDestructor = NULL;
+ accel_globals->function_table.pDestructor = accel_globals_internal_func_dtor;
zend_hash_destroy(&accel_globals->function_table);
}
@@ -2724,6 +2729,7 @@ void accel_shutdown(TSRMLS_D)
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (ZCG(accel_directives).interned_strings_buffer) {
# ifndef ZTS
+ zend_hash_clean(CG(auto_globals));
zend_hash_clean(CG(function_table));
zend_hash_clean(CG(class_table));
zend_hash_clean(EG(zend_constants));
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c
index 3769e362fe..1ea652bc46 100644
--- a/ext/opcache/zend_accelerator_util_funcs.c
+++ b/ext/opcache/zend_accelerator_util_funcs.c
@@ -49,8 +49,9 @@ static int zend_prepare_function_for_execution(zend_op_array *op_array);
static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind);
static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC);
-static void zend_accel_destroy_zend_function(zend_function *function)
+static void zend_accel_destroy_zend_function(zval *zv)
{
+ zend_function *function = Z_PTR_P(zv);
TSRMLS_FETCH();
if (function->type == ZEND_USER_FUNCTION) {
@@ -67,7 +68,7 @@ static void zend_accel_destroy_zend_function(zend_function *function)
static void zend_accel_destroy_zend_class(zval *zv)
{
zend_class_entry *ce = Z_PTR_P(zv);
- ce->function_table.pDestructor = (dtor_func_t) zend_accel_destroy_zend_function;
+ ce->function_table.pDestructor = zend_accel_destroy_zend_function;
destroy_zend_class(zv);
}
@@ -150,8 +151,8 @@ int compact_persistent_script(zend_persistent_script *persistent_script)
void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements)
{
if (destroy_elements) {
- persistent_script->function_table.pDestructor = (dtor_func_t)zend_accel_destroy_zend_function;
- persistent_script->class_table.pDestructor = (dtor_func_t)zend_accel_destroy_zend_class;
+ persistent_script->function_table.pDestructor = zend_accel_destroy_zend_function;
+ persistent_script->class_table.pDestructor = zend_accel_destroy_zend_class;
} else {
persistent_script->function_table.pDestructor = NULL;
persistent_script->class_table.pDestructor = NULL;
@@ -196,7 +197,8 @@ static int move_user_function(zval *zv
#endif
if (function->type == ZEND_USER_FUNCTION) {
- zend_hash_update_mem(function_table, hash_key->key, function, sizeof(zend_function));
+ zend_hash_update_ptr(function_table, hash_key->key, function);
+//??? zend_hash_update_mem(function_table, hash_key->key, function, sizeof(zend_function));
return 1;
} else {
return 0;
@@ -231,12 +233,15 @@ void zend_accel_copy_internal_functions(TSRMLS_D)
ZCG(internal_functions_count) = zend_hash_num_elements(&ZCG(function_table));
}
-static void zend_destroy_property_info(zend_property_info *property_info)
+static void zend_destroy_property_info(zval *zv)
{
+ zend_property_info *property_info = Z_PTR_P(zv);
+
STR_RELEASE(property_info->name);
if (property_info->doc_comment) {
STR_RELEASE(property_info->doc_comment);
}
+ efree(property_info);
}
static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC)
@@ -250,15 +255,17 @@ static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC)
#endif
case IS_STRING:
case IS_CONSTANT:
- if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_STR_P(src))) != NULL) {
- Z_STR_P(src) = ptr;
- } else {
- zend_string *old = Z_STR_P(src);
+ if (!IS_INTERNED(Z_STR_P(src))) {
+ if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_STR_P(src))) != NULL) {
+ Z_STR_P(src) = ptr;
+ } else {
+ zend_string *old = Z_STR_P(src);
- Z_STR_P(src) = STR_DUP(old, 0);
- Z_STR_P(src)->gc = old->gc;
- if (bind && Z_REFCOUNT_P(src) > 1) {
- accel_xlat_set(old, Z_STR_P(src));
+ Z_STR_P(src) = STR_DUP(old, 0);
+ Z_STR_P(src)->gc = old->gc;
+ if (bind && Z_REFCOUNT_P(src) > 1) {
+ accel_xlat_set(old, Z_STR_P(src));
+ }
}
}
break;
@@ -513,7 +520,7 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
ht->nNumUsed = 0;
ht->nNumOfElements = source->nNumOfElements;
ht->nNextFreeElement = source->nNextFreeElement;
- ht->pDestructor = (dtor_func_t) zend_destroy_property_info;
+ ht->pDestructor = zend_destroy_property_info;
#if ZEND_DEBUG
//??? ht->inconsistent = 0;
#endif
@@ -801,15 +808,17 @@ static int zend_hash_unique_copy_mem(HashTable *target, HashTable *source, uniqu
{
uint idx;
Bucket *p;
- void *t;
+ zval *t;
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
if (Z_TYPE(p->val) == IS_UNDEF) continue;
if (p->key) {
- if ((t = zend_hash_add_mem(target, p->key, Z_PTR(p->val), size)) != NULL) {
+ if ((t = zend_hash_add(target, p->key, &p->val)) != NULL) {
+ Z_PTR_P(t) = emalloc(size);
+ memcpy(Z_PTR_P(t), Z_PTR(p->val), size);
if (pCopyConstructor) {
- pCopyConstructor(t);
+ pCopyConstructor(Z_PTR_P(t));
}
} else {
if (p->key->len > 0 && p->key->val[0] == 0) {
@@ -817,29 +826,33 @@ static int zend_hash_unique_copy_mem(HashTable *target, HashTable *source, uniqu
#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
if (((zend_function*)Z_PTR(p->val))->common.fn_flags & ZEND_ACC_CLOSURE) {
/* update closure */
- if ((t = zend_hash_update_mem(target, p->key, Z_PTR(p->val), size)) != NULL) {
+ if ((t = zend_hash_update(target, p->key, &p->val)) != NULL) {
+ Z_PTR_P(t) = emalloc(size);
+ memcpy(Z_PTR_P(t), Z_PTR(p->val), size);
if (pCopyConstructor) {
- pCopyConstructor(t);
+ pCopyConstructor(Z_PTR_P(t));
}
}
} else {
/* ignore and wait for runtime */
}
#endif
- } else if (!ignore_dups && (t = zend_hash_find_ptr(target, p->key)) != NULL) {
+ } else if (!ignore_dups && (t = zend_hash_find(target, p->key)) != NULL) {
*fail_data = Z_PTR(p->val);
- *conflict_data = t;
+ *conflict_data = Z_PTR_P(t);
return FAILURE;
}
}
} else {
- if (!zend_hash_index_exists(target, p->h) && (t = zend_hash_index_update_mem(target, p->h, Z_PTR(p->val), size)) != NULL) {
+ if (!zend_hash_index_exists(target, p->h) && (t = zend_hash_index_update(target, p->h, &p->val)) != NULL) {
+ Z_PTR_P(t) = emalloc(size);
+ memcpy(Z_PTR_P(t), Z_PTR(p->val), size);
if (pCopyConstructor) {
- pCopyConstructor(t);
+ pCopyConstructor(Z_PTR_P(t));
}
- } else if (!ignore_dups && (t = zend_hash_index_find_ptr(target,p->h)) != NULL) {
+ } else if (!ignore_dups && (t = zend_hash_index_find(target,p->h)) != NULL) {
*fail_data = Z_PTR(p->val);
- *conflict_data = t;
+ *conflict_data = Z_PTR_P(t);
return FAILURE;
}
}
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
index cfac1960a2..13287025bb 100644
--- a/ext/opcache/zend_persist.c
+++ b/ext/opcache/zend_persist.c
@@ -186,7 +186,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
if (op_array->filename) {
/* do not free! PHP has centralized filename storage, compiler will free it */
- zend_accel_memdup_string(op_array->filename);
+ op_array->filename = zend_accel_memdup_string(op_array->filename);
}
if (main_persistent_script) {
@@ -354,9 +354,13 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
for (i = 0; i < op_array->num_args; i++) {
if (op_array->arg_info[i].name) {
//??? zend_accel_store_interned_string(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1);
+ efree(op_array->arg_info[i].name);
+ op_array->arg_info[i].name = NULL;
}
if (op_array->arg_info[i].class_name) {
//??? zend_accel_store_interned_string(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1);
+ efree(op_array->arg_info[i].class_name);
+ op_array->arg_info[i].class_name = NULL;
}
}
}
@@ -476,7 +480,7 @@ static void zend_persist_class_entry(zval *zv TSRMLS_DC)
if (ZEND_CE_FILENAME(ce)) {
/* do not free! PHP has centralized filename storage, compiler will free it */
- zend_accel_memdup_string(ZEND_CE_FILENAME(ce));
+ ZEND_CE_FILENAME(ce) = zend_accel_memdup_string(ZEND_CE_FILENAME(ce));
}
if (ZEND_CE_DOC_COMMENT(ce)) {
if (ZCG(accel_directives).save_comments) {
diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c
index 061a4e2777..73f331de6f 100644
--- a/ext/opcache/zend_shared_alloc.c
+++ b/ext/opcache/zend_shared_alloc.c
@@ -347,6 +347,7 @@ void *_zend_shared_memdup(void *source, size_t size, zend_bool free_source TSRML
ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
memcpy(retval, source, size);
if (free_source) {
+ efree(source);
//??? interned_efree((char*)source);
}
zend_shared_alloc_register_xlat_entry(source, retval);