--- /dev/null
+--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] => ::
+ )
+
+)
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)
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
}
}
-/* {{{ proto void debug_print_backtrace(void) */
+/* {{{ proto void debug_print_backtrace([int options]) */
ZEND_FUNCTION(debug_print_backtrace)
{
zend_execute_data *ptr, *skip;
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;
}
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);
}
}
/* }}} */
-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;
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);
}
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));
}
/* }}} */
-/* {{{ 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);
}
/* }}} */