]> granicus.if.org Git - php/commitdiff
Add options to debug_backtrace functions
authorStanislav Malyshev <stas@php.net>
Sun, 16 Jan 2011 20:39:22 +0000 (20:39 +0000)
committerStanislav Malyshev <stas@php.net>
Sun, 16 Jan 2011 20:39:22 +0000 (20:39 +0000)
Zend/tests/debug_backtrace_options.phpt [new file with mode: 0644]
Zend/zend.h
Zend/zend_builtin_functions.c
Zend/zend_constants.c

diff --git a/Zend/tests/debug_backtrace_options.phpt b/Zend/tests/debug_backtrace_options.phpt
new file mode 100644 (file)
index 0000000..1b2d7e5
--- /dev/null
@@ -0,0 +1,397 @@
+--TEST--
+debug_backtrace options
+--FILE--
+<?php
+
+function backtrace_print($opt = null)
+{
+       if(is_null($opt)) {
+               print_r(debug_backtrace());
+       } else {
+               print_r(debug_backtrace($opt));
+       }
+}
+
+function doit($a, $b, $how)
+{
+       echo "==default\n";
+       $how();
+       echo "==true\n";
+       $how(true);
+       echo "==false\n";
+       $how(false);
+       echo "==DEBUG_BACKTRACE_PROVIDE_OBJECT\n";
+       $how(DEBUG_BACKTRACE_PROVIDE_OBJECT);
+       echo "==DEBUG_BACKTRACE_IGNORE_ARGS\n";
+       $how(DEBUG_BACKTRACE_IGNORE_ARGS);
+       echo "==both\n";
+       $how(DEBUG_BACKTRACE_PROVIDE_OBJECT|DEBUG_BACKTRACE_IGNORE_ARGS);
+}
+
+class foo {
+       protected function doCall($dowhat, $how) 
+       {  
+          $dowhat('a','b', $how);
+       }
+       static function statCall($dowhat, $how)
+       {
+               $obj = new self();
+               $obj->doCall($dowhat, $how);
+       }
+}
+foo::statCall("doit", "debug_print_backtrace");
+foo::statCall("doit", "backtrace_print");
+
+?>
+--EXPECTF--
+==default
+#0  doit(a, b, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#1  foo->doCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#2  foo::statCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+==true
+#0  doit(a, b, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#1  foo->doCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#2  foo::statCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+==false
+#0  doit(a, b, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#1  foo->doCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#2  foo::statCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+==DEBUG_BACKTRACE_PROVIDE_OBJECT
+#0  doit(a, b, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#1  foo->doCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+#2  foo::statCall(doit, debug_print_backtrace) called at [%sdebug_backtrace_options.php:%d]
+==DEBUG_BACKTRACE_IGNORE_ARGS
+#0  doit() called at [%sdebug_backtrace_options.php:%d]
+#1  foo->doCall() called at [%sdebug_backtrace_options.php:%d]
+#2  foo::statCall() called at [%sdebug_backtrace_options.php:%d]
+==both
+#0  doit() called at [%sdebug_backtrace_options.php:%d]
+#1  foo->doCall() called at [%sdebug_backtrace_options.php:%d]
+#2  foo::statCall() called at [%sdebug_backtrace_options.php:%d]
+==default
+Array
+(
+    [0] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => backtrace_print
+            [args] => Array
+                (
+                )
+
+        )
+
+    [1] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doit
+            [args] => Array
+                (
+                    [0] => a
+                    [1] => b
+                    [2] => backtrace_print
+                )
+
+        )
+
+    [2] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doCall
+            [class] => foo
+            [object] => foo Object
+                (
+                )
+
+            [type] => ->
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+    [3] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => statCall
+            [class] => foo
+            [type] => ::
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+)
+==true
+Array
+(
+    [0] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => 17
+            [function] => backtrace_print
+            [args] => Array
+                (
+                    [0] => 1
+                )
+
+        )
+
+    [1] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doit
+            [args] => Array
+                (
+                    [0] => a
+                    [1] => b
+                    [2] => backtrace_print
+                )
+
+        )
+
+    [2] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doCall
+            [class] => foo
+            [object] => foo Object
+                (
+                )
+
+            [type] => ->
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+    [3] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => statCall
+            [class] => foo
+            [type] => ::
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+)
+==false
+Array
+(
+    [0] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => 19
+            [function] => backtrace_print
+            [args] => Array
+                (
+                    [0] => 
+                )
+
+        )
+
+    [1] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doit
+            [args] => Array
+                (
+                    [0] => a
+                    [1] => b
+                    [2] => backtrace_print
+                )
+
+        )
+
+    [2] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doCall
+            [class] => foo
+            [type] => ->
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+    [3] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => statCall
+            [class] => foo
+            [type] => ::
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+)
+==DEBUG_BACKTRACE_PROVIDE_OBJECT
+Array
+(
+    [0] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => 21
+            [function] => backtrace_print
+            [args] => Array
+                (
+                    [0] => 1
+                )
+
+        )
+
+    [1] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doit
+            [args] => Array
+                (
+                    [0] => a
+                    [1] => b
+                    [2] => backtrace_print
+                )
+
+        )
+
+    [2] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doCall
+            [class] => foo
+            [object] => foo Object
+                (
+                )
+
+            [type] => ->
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+    [3] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => statCall
+            [class] => foo
+            [type] => ::
+            [args] => Array
+                (
+                    [0] => doit
+                    [1] => backtrace_print
+                )
+
+        )
+
+)
+==DEBUG_BACKTRACE_IGNORE_ARGS
+Array
+(
+    [0] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => 23
+            [function] => backtrace_print
+        )
+
+    [1] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doit
+        )
+
+    [2] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doCall
+            [class] => foo
+            [type] => ->
+        )
+
+    [3] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => statCall
+            [class] => foo
+            [type] => ::
+        )
+
+)
+==both
+Array
+(
+    [0] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => 25
+            [function] => backtrace_print
+        )
+
+    [1] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doit
+        )
+
+    [2] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => doCall
+            [class] => foo
+            [object] => foo Object
+                (
+                )
+
+            [type] => ->
+        )
+
+    [3] => Array
+        (
+            [file] => %sdebug_backtrace_options.php
+            [line] => %d
+            [function] => statCall
+            [class] => foo
+            [type] => ::
+        )
+
+)
index c19387a815c03efcbeff8f966df557a0c90af754..a80526c0eb8c9f6dacf512fc8b7858670cd82191 100644 (file)
@@ -838,6 +838,9 @@ ZEND_API void zend_save_error_handling(zend_error_handling *current TSRMLS_DC);
 ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current TSRMLS_DC);
 ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC);
 
+#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
+#define DEBUG_BACKTRACE_IGNORE_ARGS    (1<<1)
+
 #endif /* ZEND_H */
 
 /*
index c0e195a254a103e6359028abb254154b1fd006d7..c4f0fbc17bfda83aa47d4bb2b7273e3990e7bf4f 100644 (file)
@@ -226,7 +226,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
-       ZEND_ARG_INFO(0, provide_object)
+       ZEND_ARG_INFO(0, options)
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
@@ -290,7 +290,7 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */
        ZEND_FE(get_extension_funcs,            arginfo_extension_loaded)
        ZEND_FE(get_defined_constants,          arginfo_get_defined_constants)
        ZEND_FE(debug_backtrace,                        arginfo_debug_backtrace)
-       ZEND_FE(debug_print_backtrace,          arginfo_zend__void)
+       ZEND_FE(debug_print_backtrace,          arginfo_debug_backtrace)
 #if ZEND_DEBUG
        ZEND_FE(zend_test_func,         NULL)
 #ifdef ZTS
@@ -2047,7 +2047,7 @@ void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
        }
 }
 
-/* {{{ proto void debug_print_backtrace(void) */
+/* {{{ proto void debug_print_backtrace([int options]) */
 ZEND_FUNCTION(debug_print_backtrace)
 {
        zend_execute_data *ptr, *skip;
@@ -2059,8 +2059,9 @@ ZEND_FUNCTION(debug_print_backtrace)
        char *include_filename = NULL;
        zval *arg_array = NULL;
        int indent = 0;
+       long options = 0;
 
-       if (zend_parse_parameters_none() == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &options) == FAILURE) {
                return;
        }
 
@@ -2119,7 +2120,7 @@ ZEND_FUNCTION(debug_print_backtrace)
                                call_type = NULL;
                        }
                        if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
-                               if (ptr->function_state.arguments) {
+                               if (ptr->function_state.arguments && (options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
                                        arg_array = debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC);
                                }
                        }
@@ -2206,7 +2207,7 @@ ZEND_FUNCTION(debug_print_backtrace)
 
 /* }}} */
 
-ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int provide_object TSRMLS_DC)
+ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options TSRMLS_DC)
 {
        zend_execute_data *ptr, *skip;
        int lineno;
@@ -2290,7 +2291,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
                                        add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, dup);
                                        
                                }
-                               if (provide_object) {
+                               if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
                                        add_assoc_zval_ex(stack_frame, "object", sizeof("object"), ptr->object);
                                        Z_ADDREF_P(ptr->object);
                                }
@@ -2301,7 +2302,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
                                add_assoc_string_ex(stack_frame, "type", sizeof("type"), "::", 1);
                        }
 
-                       if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
+                       if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 && 
+                               ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL)))) {
                                if (ptr->function_state.arguments) {
                                        add_assoc_zval_ex(stack_frame, "args", sizeof("args"), debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC));
                                }
@@ -2367,17 +2369,17 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
 /* }}} */
 
 
-/* {{{ proto array debug_backtrace([bool provide_object])
+/* {{{ proto array debug_backtrace([int options])
    Return backtrace as array */
 ZEND_FUNCTION(debug_backtrace)
 {
-       zend_bool provide_object = 1;
+       long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
        
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &provide_object) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &options) == FAILURE) {
                return;
        }
 
-       zend_fetch_debug_backtrace(return_value, 1, provide_object TSRMLS_CC);
+       zend_fetch_debug_backtrace(return_value, 1, options TSRMLS_CC);
 }
 /* }}} */
 
index 40055585263ae7b683a73e9040813f0665bca285..2a42083a837e74929a850144e04a80b024840820 100644 (file)
@@ -115,6 +115,8 @@ void zend_register_standard_constants(TSRMLS_D)
 
        REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
 
+       REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
+       REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
        /* true/false constants */
        {
                zend_constant c;