diff options
Diffstat (limited to 'Zend/zend_builtin_functions.c')
| -rw-r--r-- | Zend/zend_builtin_functions.c | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index dbe02ded5c..96b339cd67 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -2033,7 +2033,7 @@ void debug_print_backtrace_args(zval *arg_array TSRMLS_DC) /* {{{ proto void debug_print_backtrace([int options[, int limit]]) */ ZEND_FUNCTION(debug_print_backtrace) { - zend_execute_data *ptr, *skip; + zend_execute_data *call, *ptr, *skip; zend_object *object; int lineno, frameno = 0; zend_function *func; @@ -2055,7 +2055,7 @@ ZEND_FUNCTION(debug_print_backtrace) ptr = EG(current_execute_data)->prev_execute_data; /* skip debug_backtrace() */ - object = ptr->object; + call = ptr; ptr = ptr->prev_execute_data; while (ptr && (limit == 0 || frameno < limit)) { @@ -2068,7 +2068,8 @@ ZEND_FUNCTION(debug_print_backtrace) /* skip internal handler */ if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) && skip->prev_execute_data && - skip->prev_execute_data->opline && + skip->prev_execute_data->func && + ZEND_USER_CODE(skip->prev_execute_data->func->common.type) && skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL && skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) { skip = skip->prev_execute_data; @@ -2091,15 +2092,16 @@ ZEND_FUNCTION(debug_print_backtrace) } /* $this may be passed into regular internal functions */ + object = call->object; if (object && - ptr->call && - ptr->call->func->type == ZEND_INTERNAL_FUNCTION && - !ptr->call->func->common.scope) { + call && + call->func->type == ZEND_INTERNAL_FUNCTION && + !call->func->common.scope) { object = NULL; } - if (ptr->call && ptr->call->func && (ptr->call->flags & ZEND_CALL_DONE)) { - func = ptr->call->func; + if (call->func) { + func = call->func; function_name = (func->common.scope && func->common.scope->trait_aliases) ? zend_resolve_method_name( @@ -2109,9 +2111,8 @@ ZEND_FUNCTION(debug_print_backtrace) (func->common.function_name ? func->common.function_name->val : NULL); } else { - func = ptr->func; - function_name = func && func->common.function_name ? - func->common.function_name->val : NULL; + func = NULL; + function_name = NULL; } if (function_name) { @@ -2132,14 +2133,14 @@ ZEND_FUNCTION(debug_print_backtrace) } if (func->type != ZEND_EVAL_CODE) { if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) { - debug_backtrace_get_args(ptr->call, &arg_array TSRMLS_CC); + debug_backtrace_get_args(call, &arg_array TSRMLS_CC); } } } else { /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */ zend_bool build_filename_arg = 1; - if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) { + if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) { /* can happen when calling eval from a custom sapi */ function_name = "unknown"; build_filename_arg = 0; @@ -2188,12 +2189,13 @@ ZEND_FUNCTION(debug_print_backtrace) if (filename) { zend_printf(") called at [%s:%d]\n", filename, lineno); } else { + zend_execute_data *prev_call = skip; zend_execute_data *prev = skip->prev_execute_data; while (prev) { - if (prev->call && - prev->call->func && - !ZEND_USER_CODE(prev->call->func->common.type)) { + if (prev_call && + prev_call->func && + !ZEND_USER_CODE(prev_call->func->common.type)) { prev = NULL; break; } @@ -2201,6 +2203,7 @@ ZEND_FUNCTION(debug_print_backtrace) zend_printf(") called at [%s:%d]\n", prev->func->op_array.filename->val, prev->opline->lineno); break; } + prev_call = prev; prev = prev->prev_execute_data; } if (!prev) { @@ -2208,7 +2211,7 @@ ZEND_FUNCTION(debug_print_backtrace) } } include_filename = filename; - object = skip->object; + call = skip; ptr = skip->prev_execute_data; ++indent; } @@ -2218,8 +2221,8 @@ ZEND_FUNCTION(debug_print_backtrace) ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit TSRMLS_DC) { - zend_execute_data *ptr, *skip; - zend_object *object = Z_OBJ(EG(This)); + zend_execute_data *call, *ptr, *skip; + zend_object *object; int lineno, frameno = 0; zend_function *func; const char *function_name; @@ -2228,24 +2231,29 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int const char *include_filename = NULL; zval stack_frame; + call = NULL; ptr = EG(current_execute_data); - if (!ptr->opline) { + if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type)) { + call = ptr; ptr = ptr->prev_execute_data; } if (ptr) { if (skip_last) { /* skip debug_backtrace() */ - object = ptr->object; + call = ptr; ptr = ptr->prev_execute_data; } else { /* skip "new Exception()" */ - if (ptr->opline && (ptr->opline->opcode == ZEND_NEW)) { - object = ptr->object; + if (ptr->func && ZEND_USER_CODE(ptr->func->common.type) && (ptr->opline->opcode == ZEND_NEW)) { + call = ptr; ptr = ptr->prev_execute_data; } } } + if (!call) { + call = ptr; + } array_init(return_value); @@ -2257,7 +2265,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int /* skip internal handler */ if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) && skip->prev_execute_data && - skip->prev_execute_data->opline && + skip->prev_execute_data->func && + ZEND_USER_CODE(skip->prev_execute_data->func->common.type) && skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL && skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) { skip = skip->prev_execute_data; @@ -2281,14 +2290,15 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int * and debug_baktrace() might have been called by the error_handler. in this case we don't * want to pop anything of the argument-stack */ } else { + zend_execute_data *prev_call = skip; zend_execute_data *prev = skip->prev_execute_data; while (prev) { - if (prev->call && - prev->call->func && - !ZEND_USER_CODE(prev->call->func->common.type) && - !(prev->call->func->common.type == ZEND_INTERNAL_FUNCTION && - (prev->call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) { + if (prev_call && + prev_call->func && + !ZEND_USER_CODE(prev_call->func->common.type) && + !(prev_call->func->common.type == ZEND_INTERNAL_FUNCTION && + (prev_call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) { break; } if (prev->func && ZEND_USER_CODE(prev->func->common.type)) { @@ -2297,21 +2307,22 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int add_assoc_long_ex(&stack_frame, "line", sizeof("line")-1, prev->opline->lineno); break; } + prev_call = prev; prev = prev->prev_execute_data; } filename = NULL; } /* $this may be passed into regular internal functions */ + object = call ? call->object : NULL; if (object && - ptr->call && - ptr->call->func->type == ZEND_INTERNAL_FUNCTION && - !ptr->call->func->common.scope) { + call->func->type == ZEND_INTERNAL_FUNCTION && + !call->func->common.scope) { object = NULL; } - if (ptr->call && ptr->call->func && (ptr->call->flags & ZEND_CALL_DONE)) { - func = ptr->call->func; + if (call && call->func) { + func = call->func; function_name = (func->common.scope && func->common.scope->trait_aliases) ? zend_resolve_method_name( @@ -2321,9 +2332,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int (func->common.function_name ? func->common.function_name->val : NULL); } else { - func = ptr->func; - function_name = func && func->common.function_name ? - func->common.function_name->val : NULL; + func = NULL; + function_name = NULL; } if (function_name) { @@ -2352,17 +2362,16 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 && func->type != ZEND_EVAL_CODE) { - if (ptr->call) { - zval args; - debug_backtrace_get_args(ptr->call, &args TSRMLS_CC); - add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &args); - } + zval args; + + debug_backtrace_get_args(call, &args TSRMLS_CC); + add_assoc_zval_ex(&stack_frame, "args", sizeof("args")-1, &args); } } else { /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */ zend_bool build_filename_arg = 1; - if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) { + if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) { /* can happen when calling eval from a custom sapi */ function_name = "unknown"; build_filename_arg = 0; @@ -2412,7 +2421,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int include_filename = filename; - object = skip->object; + call = skip; ptr = skip->prev_execute_data; } } |
