summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2006-07-27 08:20:52 +0000
committerDmitry Stogov <dmitry@php.net>2006-07-27 08:20:52 +0000
commit0eb028291203b2ddddf7f37b87e2da45dafabfb6 (patch)
treefecc96adcbd691437c3a1397adaf9a75033e3d63
parent6d6bd77429d2e96329070249c31d63dd392a97e4 (diff)
downloadphp-git-0eb028291203b2ddddf7f37b87e2da45dafabfb6.tar.gz
Fixed bug #38047 ("file" and "line" sometimes not set in backtrace from inside error handler)
-rwxr-xr-xZend/tests/bug38047.phpt50
-rw-r--r--Zend/zend_builtin_functions.c32
2 files changed, 81 insertions, 1 deletions
diff --git a/Zend/tests/bug38047.phpt b/Zend/tests/bug38047.phpt
new file mode 100755
index 0000000000..00290ee542
--- /dev/null
+++ b/Zend/tests/bug38047.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Bug #38047 ("file" and "line" sometimes not set in backtrace from inside error handler)
+--FILE--
+<?php
+error_reporting(E_ALL);
+set_error_handler('kalus_error_handler');
+ini_set("display_errors", "on");
+
+class A {
+ function A_ftk($a) {
+ }
+}
+
+function kalus_error_handler($error_code, $error_string, $filename, $line, $symbols) {
+ echo "$error_string\n";
+ get_error_context();
+}
+
+function get_error_context() {
+ $backtrace = debug_backtrace();
+ $n = 1;
+ foreach ($backtrace as $call) {
+ echo $n++." ";
+ if (isset($call["file"])) {
+ echo $call["file"];
+ if (isset($call["line"])) {
+ echo ":".$call["line"];
+ }
+ }
+ if (isset($call["function"])) {
+ echo " ".$call["function"]."()";
+ }
+ echo "\n";
+ }
+ echo "\n";
+}
+
+//This will not create file and line items for the call into the error handler
+$page["name"] = A::A_ftk();
+?>
+--EXPECTF--
+Non-static method A::A_ftk() should not be called statically
+1 %sbug38047.php:13 get_error_context()
+2 %sbug38047.php:36 kalus_error_handler()
+3 %sbug38047.php:36 A_ftk()
+
+Missing argument 1 for A::A_ftk(), called in %sbug38047.php on line 36 and defined
+1 %sbug38047.php:13 get_error_context()
+2 %sbug38047.php:7 kalus_error_handler()
+3 %sbug38047.php:36 A_ftk()
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index e79b906e74..a5a4bb8325 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -1935,7 +1935,23 @@ ZEND_FUNCTION(debug_print_backtrace)
if (filename) {
zend_printf(") called at [%s:%d]\n", filename, lineno);
} else {
- ZEND_PUTS(")\n");
+ zend_execute_data *prev = skip->prev_execute_data;
+
+ while (prev) {
+ if (prev->function_state.function &&
+ prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
+ prev = NULL;
+ break;
+ }
+ if (prev->op_array) {
+ zend_printf(") called at [%s:%d]\n", prev->op_array->filename, prev->opline->lineno);
+ break;
+ }
+ prev = prev->prev_execute_data;
+ }
+ if (!prev) {
+ ZEND_PUTS(")\n");
+ }
}
include_filename = filename;
ptr = skip->prev_execute_data;
@@ -2029,6 +2045,20 @@ 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 = skip->prev_execute_data;
+
+ while (prev) {
+ if (prev->function_state.function &&
+ prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
+ break;
+ }
+ if (prev->op_array) {
+ add_assoc_string_ex(stack_frame, "file", sizeof("file"), prev->op_array->filename, 1);
+ add_assoc_long_ex(stack_frame, "line", sizeof("line"), prev->opline->lineno);
+ break;
+ }
+ prev = prev->prev_execute_data;
+ }
filename = NULL;
}