Skip to content
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

Do not free observed variables on unclean shutdown #1112

Merged
merged 1 commit into from Aug 19, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Do not try to free observed variables on unclean shutdown
  • Loading branch information
sjinks committed Aug 19, 2013
commit 03aae4957e1d347122612f81c74a465918e7eb87
99 changes: 51 additions & 48 deletions ext/kernel/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,75 +145,78 @@ static void phalcon_memory_restore_stack_common(zend_phalcon_globals *phalcon_gl
active_memory = phalcon_globals_ptr->active_memory;
assert(active_memory != NULL);

if (phalcon_globals_ptr->active_symbol_table) {
active_symbol_table = phalcon_globals_ptr->active_symbol_table;
if (active_symbol_table->scope == active_memory) {
zend_hash_destroy(EG(active_symbol_table));
FREE_HASHTABLE(EG(active_symbol_table));
EG(active_symbol_table) = active_symbol_table->symbol_table;
phalcon_globals_ptr->active_symbol_table = active_symbol_table->prev;
efree(active_symbol_table);
if (likely(!CG(unclean_shutdown))) {
/* Clean active symbol table */
if (phalcon_globals_ptr->active_symbol_table) {
active_symbol_table = phalcon_globals_ptr->active_symbol_table;
if (active_symbol_table->scope == active_memory) {
zend_hash_destroy(EG(active_symbol_table));
FREE_HASHTABLE(EG(active_symbol_table));
EG(active_symbol_table) = active_symbol_table->symbol_table;
phalcon_globals_ptr->active_symbol_table = active_symbol_table->prev;
efree(active_symbol_table);
}
}
}

/**
* Check for non freed hash key zvals, mark as null to avoid string freeing
*/
for (i = 0; i < active_memory->hash_pointer; ++i) {
assert(active_memory->hash_addresses[i] != NULL && *(active_memory->hash_addresses[i]) != NULL);
/**
* Check for non freed hash key zvals, mark as null to avoid string freeing
*/
for (i = 0; i < active_memory->hash_pointer; ++i) {
assert(active_memory->hash_addresses[i] != NULL && *(active_memory->hash_addresses[i]) != NULL);

#if ZEND_DEBUG
_mem_block_check(*active_memory->hash_addresses[i], 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
_mem_block_check(*active_memory->hash_addresses[i], 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#endif

if (Z_REFCOUNT_PP(active_memory->hash_addresses[i]) <= 1) {
ZVAL_NULL(*active_memory->hash_addresses[i]);
} else {
zval_copy_ctor(*active_memory->hash_addresses[i]);
if (Z_REFCOUNT_PP(active_memory->hash_addresses[i]) <= 1) {
ZVAL_NULL(*active_memory->hash_addresses[i]);
} else {
zval_copy_ctor(*active_memory->hash_addresses[i]);
}
}
}

#ifndef PHALCON_RELEASE
for (i = 0; i < active_memory->pointer; ++i) {
if (likely(active_memory->addresses[i] != NULL && *(active_memory->addresses[i]) != NULL)) {
zval **var = active_memory->addresses[i];
for (i = 0; i < active_memory->pointer; ++i) {
if (likely(active_memory->addresses[i] != NULL && *(active_memory->addresses[i]) != NULL)) {
zval **var = active_memory->addresses[i];

#if ZEND_DEBUG
_mem_block_check(*var, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
_mem_block_check(*var, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#endif

#if PHP_VERSION_ID < 50400
if (Z_TYPE_PP(var) > IS_CONSTANT_ARRAY) {
fprintf(stderr, "%s: observed variable #%d (%p) has invalid type %u\n", __func__, (int)i, *var, Z_TYPE_PP(var));
}
if (Z_TYPE_PP(var) > IS_CONSTANT_ARRAY) {
fprintf(stderr, "%s: observed variable #%d (%p) has invalid type %u\n", __func__, (int)i, *var, Z_TYPE_PP(var));
}
#else
if (Z_TYPE_PP(var) > IS_CALLABLE) {
fprintf(stderr, "%s: observed variable #%d (%p) has invalid type %u\n", __func__, (int)i, *var, Z_TYPE_PP(var));
}
if (Z_TYPE_PP(var) > IS_CALLABLE) {
fprintf(stderr, "%s: observed variable #%d (%p) has invalid type %u\n", __func__, (int)i, *var, Z_TYPE_PP(var));
}
#endif

if (Z_REFCOUNT_PP(var) == 0) {
fprintf(stderr, "%s: observed variable #%d (%p) has 0 references\n", __func__, (int)i, *var);
}
else if (Z_REFCOUNT_PP(var) >= 1000000) {
fprintf(stderr, "%s: observed variable #%d (%p) has too many references (%u)\n", __func__, (int)i, *var, Z_REFCOUNT_PP(var));
}
else if (Z_REFCOUNT_PP(var) == 1 && Z_ISREF_PP(var)) {
fprintf(stderr, "%s: observed variable #%d (%p) is a reference with reference count = 1\n", __func__, (int)i, *var);
if (Z_REFCOUNT_PP(var) == 0) {
fprintf(stderr, "%s: observed variable #%d (%p) has 0 references\n", __func__, (int)i, *var);
}
else if (Z_REFCOUNT_PP(var) >= 1000000) {
fprintf(stderr, "%s: observed variable #%d (%p) has too many references (%u)\n", __func__, (int)i, *var, Z_REFCOUNT_PP(var));
}
else if (Z_REFCOUNT_PP(var) == 1 && Z_ISREF_PP(var)) {
fprintf(stderr, "%s: observed variable #%d (%p) is a reference with reference count = 1\n", __func__, (int)i, *var);
}
}
}
}
#endif

/**
* Traverse all zvals allocated, reduce the reference counting or free them
*/
for (i = 0; i < active_memory->pointer; ++i) {
if (likely(active_memory->addresses[i] != NULL && *(active_memory->addresses[i]) != NULL)) {
if (Z_REFCOUNT_PP(active_memory->addresses[i]) == 1) {
zval_ptr_dtor(active_memory->addresses[i]);
} else {
Z_DELREF_PP(active_memory->addresses[i]);
/**
* Traverse all zvals allocated, reduce the reference counting or free them
*/
for (i = 0; i < active_memory->pointer; ++i) {
if (likely(active_memory->addresses[i] != NULL && *(active_memory->addresses[i]) != NULL)) {
if (Z_REFCOUNT_PP(active_memory->addresses[i]) == 1) {
zval_ptr_dtor(active_memory->addresses[i]);
} else {
Z_DELREF_PP(active_memory->addresses[i]);
}
}
}
}
Expand Down
66 changes: 6 additions & 60 deletions ext/phalcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,37 +359,6 @@ static void (*orig_execute_internal)(zend_execute_data *, zend_fcall_info *, int
static void (*orig_execute_internal)(zend_execute_data *, int TSRMLS_DC) = NULL;
#endif

static void (*old_error_cb)(int, const char *, const uint, const char *, va_list) = NULL;

static void phalcon_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args)
{
if (type == E_ERROR || type == E_CORE_ERROR || type == E_RECOVERABLE_ERROR || type == E_COMPILE_ERROR || type == E_USER_ERROR) {
TSRMLS_FETCH();
phalcon_clean_restore_stack(TSRMLS_C);
}

if (likely(old_error_cb != NULL)) {
/**
* va_copy() is __va_copy() in old gcc versions.
* According to the autoconf manual, using memcpy(&dst, &src, sizeof(va_list))
* gives maximum portability.
*/
#ifndef va_copy
# ifdef __va_copy
# define va_copy(dest, src) __va_copy((dest), (src))
# else
# define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
# endif
#endif
va_list copy;
va_copy(copy, args);
old_error_cb(type, error_filename, error_lineno, format, copy);
va_end(copy);
}
else {
exit(255);
}
}
#if PHP_VERSION_ID >= 50500

static void phalcon_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC)
Expand Down Expand Up @@ -420,27 +389,6 @@ static void phalcon_execute_internal(zend_execute_data *execute_data_ptr, int re

static PHP_MINIT_FUNCTION(phalcon){

if (!spl_ce_Countable) {
fprintf(stderr, "Phalcon Error: Interface Countable was not found");
return FAILURE;
}
if (!zend_ce_iterator) {
fprintf(stderr, "Phalcon Error: Interface Iterator was not found");
return FAILURE;
}
if (!zend_ce_arrayaccess) {
fprintf(stderr, "Phalcon Error: Interface ArrayAccess was not found");
return FAILURE;
}
if (!zend_ce_serializable) {
fprintf(stderr, "Phalcon Error: Interface Serializable was not found");
return FAILURE;
}
if (!spl_ce_SeekableIterator) {
fprintf(stderr, "Phalcon Error: Interface SeekableIterator was not found");
return FAILURE;
}

PHALCON_INIT(Phalcon_DI_InjectionAwareInterface);
PHALCON_INIT(Phalcon_Forms_ElementInterface);
PHALCON_INIT(Phalcon_Mvc_Model_ValidatorInterface);
Expand Down Expand Up @@ -755,9 +703,6 @@ static PHP_MINIT_FUNCTION(phalcon){
PHALCON_INIT(Phalcon_Image_Adapter_GD);
PHALCON_INIT(Phalcon_Image_Adapter_Imagick);

old_error_cb = zend_error_cb;
zend_error_cb = phalcon_error_cb;

orig_execute_internal = zend_execute_internal;
if (!zend_execute_internal) {
zend_execute_internal = phalcon_execute_internal;
Expand All @@ -766,18 +711,16 @@ static PHP_MINIT_FUNCTION(phalcon){
return SUCCESS;
}


#ifndef PHALCON_RELEASE
static PHP_MSHUTDOWN_FUNCTION(phalcon){

zend_error_cb = old_error_cb;
zend_execute_internal = orig_execute_internal;

assert(PHALCON_GLOBAL(function_cache) == NULL);
assert(PHALCON_GLOBAL(orm).parser_cache == NULL);
assert(PHALCON_GLOBAL(orm).ast_cache == NULL);

return SUCCESS;
}
#endif

static PHP_RINIT_FUNCTION(phalcon){

Expand Down Expand Up @@ -867,7 +810,11 @@ zend_module_entry phalcon_module_entry = {
PHP_PHALCON_EXTNAME,
NULL,
PHP_MINIT(phalcon),
#ifndef PHALCON_RELEASE
PHP_MSHUTDOWN(phalcon),
#else
NULL
#endif
PHP_RINIT(phalcon),
PHP_RSHUTDOWN(phalcon),
PHP_MINFO(phalcon),
Expand All @@ -882,4 +829,3 @@ zend_module_entry phalcon_module_entry = {
#ifdef COMPILE_DL_PHALCON
ZEND_GET_MODULE(phalcon)
#endif