]> granicus.if.org Git - php/commitdiff
Fixed bug #38047 ("file" and "line" sometimes not set in backtrace from inside error...
authorDmitry Stogov <dmitry@php.net>
Thu, 27 Jul 2006 08:20:38 +0000 (08:20 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 27 Jul 2006 08:20:38 +0000 (08:20 +0000)
NEWS
Zend/tests/bug38047.phpt [new file with mode: 0755]
Zend/zend_builtin_functions.c

diff --git a/NEWS b/NEWS
index 030f6fbd43c57f32b2e8933f7d4bc892a826399d..3cc557df485d7e1b0a9bd681b4a356ada7a5d0a4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,8 @@ PHP                                                                        NEWS
   itself). (Ilia)
 - Fixed bug #38132 (ReflectionClass::getStaticProperties() retains \0 in key
   names). (Ilia)
+- Fixed bug #38047 ("file" and "line" sometimes not set in backtrace from
+  inside error handler). (Dmitry)
 - Fixed bug #37564 (AES privacy encryption not possible due to net-snmp 5.2
   compatibility issue). (Jani, patch by scott dot moynes+php at gmail dot com)
 
diff --git a/Zend/tests/bug38047.phpt b/Zend/tests/bug38047.phpt
new file mode 100755 (executable)
index 0000000..00290ee
--- /dev/null
@@ -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()
index 89366b0c6d52c95ee6e4d7f8d7cafe2bb3c23fc0..06355a968943e784c25983e6e41fefdf2419622c 100644 (file)
@@ -1843,7 +1843,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;
@@ -1924,7 +1940,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
                    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;
+                       skip = skip->prev_execute_data;
                }
 
                if (skip->op_array) {
@@ -1937,6 +1953,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;
                }