diff options
| author | Dmitry Stogov <dmitry@php.net> | 2005-06-22 15:26:05 +0000 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@php.net> | 2005-06-22 15:26:05 +0000 |
| commit | da2ab061114decc4db93d85c8b3f60d47102247a (patch) | |
| tree | f417baab71db56b244d11a6160eb4ffda1a48ab8 | |
| parent | 00f14fbd74e09823f21938e523e33e0716733de0 (diff) | |
| download | php-git-da2ab061114decc4db93d85c8b3f60d47102247a.tar.gz | |
Fixed bug #29896 (Backtrace argument list out of sync)
| -rw-r--r-- | NEWS | 1 | ||||
| -rwxr-xr-x | Zend/tests/bug29896.phpt | 28 | ||||
| -rw-r--r-- | Zend/zend_builtin_functions.c | 50 | ||||
| -rw-r--r-- | Zend/zend_execute_API.c | 2 |
4 files changed, 70 insertions, 11 deletions
@@ -4,6 +4,7 @@ PHP NEWS - Fixed bug #33427 (ext/odbc: check if unixODBC header file exists). (Jani) - Fixed bug #33257 (array_splice() inconsistent when passed function instead of variable). (Dmitry) +- Fixed bug #29896 (Backtrace argument list out of sync). (Dmitry) - Fixed bug #15854 (boolean ini options may be incorrectly displayed as Off when they are On). (Tony) diff --git a/Zend/tests/bug29896.phpt b/Zend/tests/bug29896.phpt new file mode 100755 index 0000000000..1e2eb0b067 --- /dev/null +++ b/Zend/tests/bug29896.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #29896 (Backtrace argument list out of sync) +--FILE-- +<?php +function userErrorHandler($num, $msg, $file, $line, $vars) +{ + debug_print_backtrace(); +} + +$OldErrorHandler = set_error_handler("userErrorHandler"); + +function GenerateError1($A1) +{ + $a = $b; +} + +function GenerateError2($A1) +{ + GenerateError1("Test1"); +} + +GenerateError2("Test2"); +?> +--EXPECTF-- +#0 userErrorHandler(8, Undefined variable: b, %sbug29896.php, 11, Array ([A1] => Test1)) called at [%sbug29896.php:11] +#1 GenerateError1(Test1) called at [%sbug29896.php:16] +#2 GenerateError2(Test2) called at [%sbug29896.php:19] + diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 9fb2bfd68d..df4e7bd3ee 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1644,7 +1644,7 @@ void debug_print_backtrace_args(zval *arg_array TSRMLS_DC) /* {{{ proto void debug_print_backtrace(void) */ ZEND_FUNCTION(debug_print_backtrace) { - zend_execute_data *ptr; + zend_execute_data *ptr, *skip; int lineno; char *function_name; char *filename; @@ -1689,9 +1689,21 @@ ZEND_FUNCTION(debug_print_backtrace) class_name = call_type = NULL; arg_array = NULL; - if (ptr->op_array) { - filename = ptr->op_array->filename; - lineno = ptr->opline->lineno; + + skip = ptr; + /* skip internal handler */ + if (!skip->op_array && + skip->prev_execute_data && + skip->prev_execute_data->opline && + skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME && + skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) { + skip = skip->prev_execute_data; + } + + if (skip->op_array) { + filename = skip->op_array->filename; + lineno = skip->opline->lineno; } else { filename = NULL; lineno = 0; @@ -1770,7 +1782,7 @@ ZEND_FUNCTION(debug_print_backtrace) } zend_printf(") called at [%s:%d]\n", filename, lineno); include_filename = filename; - ptr = ptr->prev_execute_data; + ptr = skip->prev_execute_data; ++indent; if (free_class_name) { efree(free_class_name); @@ -1782,7 +1794,7 @@ ZEND_FUNCTION(debug_print_backtrace) ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last TSRMLS_DC) { - zend_execute_data *ptr; + zend_execute_data *ptr, *skip; int lineno; char *function_name; char *filename; @@ -1809,12 +1821,17 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last TSRML ptr = EG(current_execute_data); + /* skip "new Exception()" */ + if ((skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) { + ptr = ptr->prev_execute_data; + } + /* skip debug_backtrace() */ - ptr = ptr->prev_execute_data; if (skip_last--) { int arg_count = *((ulong*)(cur_arg_pos - 2)); cur_arg_pos -= (arg_count + 2); frames_on_stack--; + ptr = ptr->prev_execute_data; } array_init(return_value); @@ -1823,9 +1840,20 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last TSRML MAKE_STD_ZVAL(stack_frame); array_init(stack_frame); - if (ptr->op_array) { - filename = ptr->op_array->filename; - lineno = ptr->opline->lineno; + skip = ptr; + /* skip internal handler */ + if (!skip->op_array && + skip->prev_execute_data && + skip->prev_execute_data->opline && + skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME && + skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) { + skip = skip->prev_execute_data; + } + + if (skip->op_array) { + filename = skip->op_array->filename; + lineno = skip->opline->lineno; add_assoc_string_ex(stack_frame, "file", sizeof("file"), filename, 1); add_assoc_long_ex(stack_frame, "line", sizeof("line"), lineno); @@ -1916,7 +1944,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last TSRML include_filename = filename; - ptr = ptr->prev_execute_data; + ptr = skip->prev_execute_data; } } /* }}} */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 8c527ec591..82e59f7651 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -587,6 +587,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS /* Initialize execute_data */ if (EG(current_execute_data)) { execute_data = *EG(current_execute_data); + EX(op_array) = NULL; + EX(opline) = NULL; } else { /* This only happens when we're called outside any execute()'s * It shouldn't be strictly necessary to NULL execute_data out, |
