--- /dev/null
+--TEST--
+Bug #30828 (debug_backtrace() reports incorrect class in overridden methods)
+--FILE--
+<?php
+class A {
+ function __construct() {
+ debug_print_backtrace();
+ $bt = debug_backtrace();
+ foreach ($bt as $t) {
+ print $t['class'].$t['type'].$t['function']."\n";
+ }
+ }
+
+ function foo() {
+ debug_print_backtrace();
+ $bt = debug_backtrace();
+ foreach ($bt as $t) {
+ print $t['class'].$t['type'].$t['function']."\n";
+ }
+ }
+
+ static function bar() {
+ debug_print_backtrace();
+ $bt = debug_backtrace();
+ foreach ($bt as $t) {
+ print $t['class'].$t['type'].$t['function']."\n";
+ }
+ }
+}
+
+class B extends A {
+ function __construct() {
+ parent::__construct();
+ }
+
+ function foo() {
+ parent::foo();
+ }
+
+ static function bar() {
+ parent::bar();
+ }
+}
+
+$b = new B();
+$b->foo();
+B::bar();
+?>
+--EXPECTF--
+#0 A->__construct() called at [%sbug30828.php:30]
+#1 B->__construct() called at [%sbug30828.php:42]
+A->__construct
+B->__construct
+#0 A->foo() called at [%sbug30828.php:34]
+#1 B->foo() called at [%sbug30828.php:43]
+A->foo
+B->foo
+#0 A::bar() called at [%sbug30828.php:38]
+#1 B::bar() called at [%sbug30828.php:44]
+A::bar
+B::bar
if (function_name) {
if (ptr->object) {
- zend_uint class_name_len;
- if (Z_OBJ_HT_P(ptr->object)->get_class_name == NULL ||
- Z_OBJ_HT_P(ptr->object)->get_class_name(ptr->object, &class_name, &class_name_len, 0 TSRMLS_CC) != SUCCESS) {
-
- class_name = Z_OBJCE(*ptr->object)->name;
+ if (ptr->function_state.function->common.scope) {
+ class_name = ptr->function_state.function->common.scope->name;
} else {
- free_class_name = class_name;
+ zend_uint class_name_len;
+ if (Z_OBJ_HT_P(ptr->object)->get_class_name == NULL ||
+ Z_OBJ_HT_P(ptr->object)->get_class_name(ptr->object, &class_name, &class_name_len, 0 TSRMLS_CC) != SUCCESS) {
+ class_name = Z_OBJCE(*ptr->object)->name;
+ } else {
+ free_class_name = class_name;
+ }
}
call_type = "->";
} else if (ptr->function_state.function->common.scope) {
add_assoc_string_ex(stack_frame, "function", sizeof("function"), function_name, 1);
if (ptr->object && Z_TYPE_P(ptr->object) == IS_OBJECT) {
- zend_uint class_name_len;
- if (Z_OBJ_HT_P(ptr->object)->get_class_name == NULL ||
- Z_OBJ_HT_P(ptr->object)->get_class_name(ptr->object, &class_name, &class_name_len, 0 TSRMLS_CC) != SUCCESS) {
- add_assoc_string_ex(stack_frame, "class", sizeof("class"), Z_OBJCE(*ptr->object)->name, 1);
+ if (ptr->function_state.function->common.scope) {
+ add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
} else {
- add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, 0);
+ zend_uint class_name_len;
+ if (Z_OBJ_HT_P(ptr->object)->get_class_name == NULL ||
+ Z_OBJ_HT_P(ptr->object)->get_class_name(ptr->object, &class_name, &class_name_len, 0 TSRMLS_CC) != SUCCESS) {
+ add_assoc_string_ex(stack_frame, "class", sizeof("class"), Z_OBJCE(*ptr->object)->name, 1);
+ } else {
+ add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, 0);
+ }
}
add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1);
} else if (ptr->function_state.function->common.scope) {