From 931ebe08d7af6f37cb3975dd6fec07449aff0a8f Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Sat, 21 Jul 2001 14:25:27 +0000 Subject: [PATCH] Improve bailout mechanism, supports nesting of bailouts a-la try..catch --- Zend/zend.c | 26 +++++++++++++++++--------- Zend/zend.h | 32 +++++++++++++++++++++++++++----- Zend/zend_execute_API.c | 8 ++++---- Zend/zend_globals.h | 1 + Zend/zend_list.c | 4 ++-- 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 87717b19841..aec445a431c 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -464,11 +464,15 @@ void zenderror(char *error) BEGIN_EXTERN_C() -ZEND_API void zend_bailout() +ZEND_API void _zend_bailout(ZEND_FILE_LINE_D) { CLS_FETCH(); ELS_FETCH(); + if (!EG(bailout_set)) { + zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", ZEND_FILE_LINE_RELAY_C); + exit(-1); + } CG(unclean_shutdown) = 1; CG(in_compilation) = EG(in_execution) = 0; longjmp(EG(bailout), FAILURE); @@ -506,6 +510,7 @@ ZEND_API char *get_zend_version() void zend_activate(CLS_D ELS_DC) { + EG(bailout_set) = 0; init_compiler(CLS_C ELS_CC); init_executor(CLS_C ELS_CC); startup_scanner(CLS_C); @@ -522,9 +527,9 @@ void zend_deactivate_modules() ELS_FETCH(); EG(opline_ptr) = NULL; /* we're no longer executing anything */ - if (setjmp(EG(bailout))==0) { + zend_try { zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_cleanup); - } + } zend_end_try(); } void zend_deactivate(CLS_D ELS_DC) @@ -533,17 +538,20 @@ void zend_deactivate(CLS_D ELS_DC) EG(opline_ptr) = NULL; EG(active_symbol_table) = NULL; - if (setjmp(EG(bailout))==0) { + zend_try { shutdown_scanner(CLS_C); - } + } zend_end_try(); + /* shutdown_executor() takes care of its own bailout handling */ shutdown_executor(ELS_C); - if (setjmp(EG(bailout))==0) { + + zend_try { shutdown_compiler(CLS_C); - } - if (setjmp(EG(bailout))==0) { + } zend_end_try(); + + zend_try { zend_ini_deactivate(ELS_C); - } + } zend_end_try(); } diff --git a/Zend/zend.h b/Zend/zend.h index 590b5167e0c..6ff6feacb57 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -305,18 +305,40 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i void zend_shutdown(void); void zend_set_utility_values(zend_utility_values *utility_values); -BEGIN_EXTERN_C() -ZEND_API void zend_bailout(void); -END_EXTERN_C() -ZEND_API char *get_zend_version(void); +BEGIN_EXTERN_C() +ZEND_API void _zend_bailout(ZEND_FILE_LINE_D); +END_EXTERN_C() + +#if ZEND_DEBUG +#define zend_bailout() _zend_bailout(ZEND_FILE_LINE_C) +#else +#define zend_bailout() _zend_bailout() +#endif + +#define zend_try \ + { \ + jmp_buf orig_bailout; \ + zend_bool orig_bailout_set=EG(bailout_set); \ + \ + EG(bailout_set) = 1; \ + memcpy(&orig_bailout, &EG(bailout), sizeof(jmp_buf)); \ + if (setjmp(EG(bailout))==0) +#define zend_catch \ + else +#define zend_end_try() \ + memcpy(&EG(bailout), &orig_bailout, sizeof(jmp_buf)); \ + EG(bailout_set) = orig_bailout_set; \ + } + +ZEND_API char *get_zend_version(void); ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy); ZEND_API int zend_print_zval(zval *expr, int indent); ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent); ZEND_API void zend_print_zval_r(zval *expr, int indent); ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent); - ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...); + #if ZEND_DEBUG #define Z_DBG(expr) (expr) #else diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0e64a38c6cd..d33764eee61 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -152,7 +152,7 @@ void init_executor(CLS_D ELS_DC) void shutdown_executor(ELS_D) { - if (setjmp(EG(bailout))==0) { + zend_try { zend_ptr_stack_destroy(&EG(arg_types_stack)); while (EG(symtable_cache_ptr)>=EG(symtable_cache)) { @@ -175,13 +175,13 @@ void shutdown_executor(ELS_D) /* Destroy all op arrays */ zend_hash_apply(EG(function_table), (int (*)(void *)) is_not_internal_function); zend_hash_apply(EG(class_table), (int (*)(void *)) is_not_internal_class); - } + } zend_end_try(); zend_destroy_rsrc_list(ELS_C); /* must be destroyed after the main symbol table and * op arrays are destroyed. */ - if (setjmp(EG(bailout))==0) { + zend_try { clean_non_persistent_constants(); #if ZEND_DEBUG signal(SIGSEGV, original_sigsegv_handler); @@ -198,7 +198,7 @@ void shutdown_executor(ELS_D) zend_ptr_stack_destroy(&EG(user_error_handlers)); EG(error_reporting) = EG(orig_error_reporting); - } + } zend_end_try(); } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index ce0f67e9910..1e2ee909f79 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -169,6 +169,7 @@ struct _zend_executor_globals { int ticks_count; zend_bool in_execution; + zend_bool bailout_set; /* for extended information support */ zend_bool no_extensions; diff --git a/Zend/zend_list.c b/Zend/zend_list.c index a4a567b26d9..218192efc44 100644 --- a/Zend/zend_list.c +++ b/Zend/zend_list.c @@ -246,9 +246,9 @@ void zend_destroy_rsrc_list(ELS_D) ht->pListTail = q; if (ht->pDestructor) { - if (setjmp(EG(bailout))==0) { + zend_try { ht->pDestructor(p->pData); - } + } zend_end_try(); } if (!p->pDataPtr && p->pData) { pefree(p->pData, ht->persistent);