Re: PATCH: debug_backtrace() function for 4.3-dev/ZE1

From: Date: Sun, 18 Aug 2002 17:19:52 +0000
Subject: Re: PATCH: debug_backtrace() function for 4.3-dev/ZE1
References: 1 2 3 4 5  Groups: php.dev 
Request: Send a blank email to php-dev+get-87007@lists.php.net to get a copy of this message
I haven't, because of the two reasons I mentioned. There's nothing about the specifics of the patch that can make me change my personal mind about it... I understand you disagree with me about the momentum issue, so let's agree to disagree. Zeev At 20:12 18/08/2002, Thies C. Arntzen wrote:
    there is one tiny change that might destabelize the ZE1 - i
    asked if you could take a look and see if you agree with
    me that this change is actually *not* harmful.
    i don't really see your point that having debug_backtrace
    only available in ZE2 will bring more momentum to the ZE2
    development. and not wanting a new (and btw very useful
    feature) in ZE1 for that very reason is not good IMHO.
    zeev, andi - have you had a *look* at the patch and do you see
    any good reason not to have it in 4.3? i do not buy you "lets
    only bring ZE2 forward" argument at all.
    i'd love to hear more opinions on this.
    tc
On Sun, Aug 18, 2002 at 06:40:35PM +0300, Andi Gutmans wrote: I also think we should make sure enough people have motivation to move to ZE2. If not it'll be hard to push it out and we all know that it's a very important step for PHP. As it is, there is still not enough momentum behind it. Andi At 05:38 PM 8/18/2002 +0300, Zeev Suraski wrote:
I said before - I prefer not having any changes in ZE1, for both
stability
reasons and also as a motivation to get ZE2 out the door more quickly. Zeev At 17:21 18/08/2002, Thies C. Arntzen wrote:
if noone objects i'm going to commit this to -HEAD (and we can start discussing it then;-) re, tc On Fri, Aug 16, 2002 at 07:39:59PM +0200, Thies C. Arntzen wrote:
    hi,
    this patch adds the extremely useful debug_backtrace()
    function to ZE1.  as it's more-or-less the same
    implementation as in ZE2 so it should be "fast and efficient"
    enough for inclusion in 4.3 IMHO.
    it has one extra feature over the ZE2 implementation by
    giving some extra information if a method was called
    using :: or -> (see the 'type' attribute in the array
    returned by debug_backtrace).
    zeev, andi one question: i had to comment line 1628 (just
    apply the patch and see for yourself) to make the following
    code work correctly (= show the class in the backtrace):
<?php class a {
      function dump() {
              var_dump(debug_backtrace());
      }
} $a = new a; $a->dump(); ?>
    (just uncomment line 1628 in the patched sources and see how
    the output of debug_backtrace doesn't show the class-name for
    this script any more)
    i don't think that commenting this line will have any
    side-effect as EG(object).ptr will be re-initialized in 1665
    and i don't see any references to it in between.
    i'd love to have this included in 4.3.0 and i think a lot of
    people would be happy as well.
    implementation:
    to make this whole thing work i simply added the class_entry
    to the execute_data and am pushing and popping it together
    with (object).ptr.
    if this patch gets accepted i'll add an php.ini seting so
    that errors and warnings will optionally have the full
    call-stack.
    comments are welcome - especially from andi & zeev.
    tc
    PS: patch is against -HEAD
-- Thies C. Arnzten - Looking for all sorts of freelance
work - just ask..
Whishlist:
http://www.amazon.de/exec/obidos/wishlist/AB9DY62QWDSZ/ref=wl_em_to
? ext/tca_prof Index: Zend/zend_builtin_functions.c =================================================================== RCS file: /repository/Zend/zend_builtin_functions.c,v retrieving revision 1.118 diff -u -r1.118 zend_builtin_functions.c
--- Zend/zend_builtin_functions.c     12 Jun 2002 17:02:22
-0000 1.118
+++ Zend/zend_builtin_functions.c 16 Aug 2002 17:22:01 -0000 @@ -65,6 +65,7 @@ static ZEND_FUNCTION(extension_loaded); static ZEND_FUNCTION(get_extension_funcs); static ZEND_FUNCTION(get_defined_constants); +static ZEND_FUNCTION(debug_backtrace); #if ZEND_DEBUG static ZEND_FUNCTION(zend_test_func); #endif @@ -116,6 +117,7 @@
      ZEND_FE(extension_loaded,                       NULL)
      ZEND_FE(get_extension_funcs,            NULL)
      ZEND_FE(get_defined_constants,          NULL)
+     ZEND_FE(debug_backtrace,                        NULL)
#if ZEND_DEBUG
      ZEND_FE(zend_test_func,         NULL)
#endif @@ -1133,6 +1135,69 @@
      array_init(return_value);
      zend_hash_apply_with_argument(EG(zend_constants),
(apply_func_arg_t) add_constant_info, return_value TSRMLS_CC);
} + +/* {{{ proto void debug_backtrace(void) + Prints out a backtrace */ +ZEND_FUNCTION(debug_backtrace) +{
+     zend_execute_data *ptr;
+     int lineno;
+     char *function_name;
+     char *filename;
+     char *class_name;
+     zend_uint class_name_length;
+     zval *stack_frame;
+
+     ptr = EG(execute_data_ptr);
+
+     /* Skip debug_backtrace() itself */
+     ptr = ptr->prev_execute_data;
+
+     array_init(return_value);
+
+     while (ptr) {
+             MAKE_STD_ZVAL(stack_frame);
+             array_init(stack_frame);
+ +
+/*           if (ptr->object) {
+                     class_name = Z_OBJCE(*ptr->object)->name;
+                     class_name_length =
Z_OBJCE(*ptr->object)->name_length;
+             }
+             if (ptr->function_state.function->common.scope) {
+                     class_name =
ptr->function_state.function->common.scope->name;
+             }
+*/
+             if (ptr->ce) {
+                     add_assoc_string_ex(stack_frame, "type",
sizeof("type"), "::", 1);
+                     class_name = ptr->ce->name;
+             } else if (ptr->object.ptr) {
+                     add_assoc_string_ex(stack_frame, "type",
sizeof("type"), "->", 1);
+                     class_name = ptr->object.ptr->value.obj.ce->name;
+
+             } else {
+                     class_name = NULL;
+             }
+
+             function_name =
ptr->function_state.function->common.function_name;
+
+             filename = ptr->op_array->filename;
+             lineno = ptr->opline->lineno;
+
+             if (function_name) {
+                     add_assoc_string_ex(stack_frame, "function",
sizeof("function"), function_name, 1);
+             }
+             if (class_name) {
+                     add_assoc_string_ex(stack_frame, "class",
sizeof("class"), class_name, 1);
+             }
+             add_assoc_string_ex(stack_frame, "file", sizeof("file"),
filename, 1);
+             add_assoc_long_ex(stack_frame, "line", sizeof("line"),
lineno);
+             add_next_index_zval(return_value, stack_frame);
+
+             ptr = ptr->prev_execute_data;
+     }
+} +/* }}} */ /* {{{ proto bool extension_loaded(string extension_name) Index: Zend/zend_execute.c =================================================================== RCS file: /repository/Zend/zend_execute.c,v retrieving revision 1.300 diff -u -r1.300 zend_execute.c
--- Zend/zend_execute.c       2 Aug 2002 20:21:38 -0000       1.300
+++ Zend/zend_execute.c       16 Aug 2002 17:22:02 -0000
@@ -1000,14 +1000,17 @@ {
      zend_execute_data execute_data;
-     EG(execute_data_ptr) = &execute_data;
-
      /* Initialize execute_data */
      EX(fbc) = NULL;
+     EX(ce) = NULL;
      EX(object).ptr = NULL;
+     EX(op_array) = op_array;
      EX(Ts) = (temp_variable *)
do_alloca(sizeof(temp_variable)*op_array->T);
+     EX(prev_execute_data) = EG(execute_data_ptr);
      EX(original_in_execution)=EG(in_execution);
+     EG(execute_data_ptr) = &execute_data;
+
      EG(in_execution) = 1;
      if (op_array->start_op) {
              EX(opline) = op_array->start_op;
@@ -1479,7 +1482,7 @@
                                      HashTable *active_function_table;
                                      zval tmp;
- zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(fbc),
EX(object).ptr);
+ zend_ptr_stack_n_push(&EG(arg_types_stack), 3, EX(fbc),
EX(object).ptr, EX(ce));
                                      if (EX(opline)->extended_value &
ZEND_CTOR_CALL) {
                                              /* constructor call */
@@ -1497,10 +1500,9 @@
                                      convert_to_string(&tmp);
                                      function_name = &tmp;
zend_str_tolower(tmp.value.str.val, tmp.value.str.len); -
+                                     EX(ce) = NULL;
                                      if (EX(opline)->op1.op_type !=
IS_UNUSED) {
                                              if
(EX(opline)->op1.op_type==IS_CONST) { /* used for class_name::function() */
-                                                     zend_class_entry
*ce;
                                                      zval
**object_ptr_ptr;
                                                      if
(zend_hash_find(EG(active_symbol_table), "this", sizeof("this"), (void **) &object_ptr_ptr)==FAILURE) {
@@ -1511,10 +1513,10 @@ EX(object).ptr = *object_ptr_ptr; EX(object).ptr->refcount++; /* For this pointer */
                                                      }
-                                                     if
(zend_hash_find(EG(class_table), EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.len+1, (void **) &ce)==FAILURE) { /* class doesn't exist */
+                                                     if
(zend_hash_find(EG(class_table), EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.len+1, (void **) &EX(ce))==FAILURE) { /* class doesn't exist */
zend_error(E_ERROR, "Undefined class name '%s'",
EX(opline)->op1.u.constant.value.str.val);
                                                      }
- active_function_table = &ce->function_table; + active_function_table = &EX(ce)->function_table;
                                              } else { /* used for
member function calls */
                                                      EX(object).ptr =
_get_object_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1) TSRMLS_CC);
@@ -1572,8 +1574,9 @@
                                              zend_error(E_ERROR,
"Unknown function: %s()\n", fname->value.str.val);
                                      }
                                      FREE_OP(EX(Ts),
&EX(opline)->op1, EG(free_op1));
- zend_ptr_stack_push(&EG(arg_types_stack), EX(object).ptr); + zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr,
EX(ce));
                                      EX(object).ptr = NULL;
+                                     EX(ce) = NULL;
                                      goto do_fcall_common;
                              }
do_fcall_common: @@ -1623,7 +1626,7 @@ zend_error(E_WARNING, "Problem with method call - please report this
bug");
                                      }
                                                      *this_ptr =
EX(object).ptr;
-                                                     EX(object).ptr =
NULL;
+                                     /*              EX(object).ptr =
NULL; */
                                              }
                                              original_return_value =
EG(return_value_ptr_ptr);
                                              EG(return_value_ptr_ptr)
= EX(Ts)[EX(opline)->result.u.var].var.ptr_ptr;
@@ -1659,9 +1662,9 @@
                                              }
                                      }
                                      if (EX(opline)->opcode ==
ZEND_DO_FCALL_BY_NAME) {
- zend_ptr_stack_n_pop(&EG(arg_types_stack), 2, &EX(object).ptr,
&EX(fbc));
+ zend_ptr_stack_n_pop(&EG(arg_types_stack), 3, &EX(ce),
&EX(object).ptr, &EX(fbc));
                                      } else {
-                                             EX(object).ptr =
zend_ptr_stack_pop(&EG(arg_types_stack));
+ zend_ptr_stack_n_pop(&EG(arg_types_stack), 2, &EX(ce),
&EX(object).ptr);
                                      }
                                      EX(function_state).function =
(zend_function *) op_array;
                                      EG(function_state_ptr) =
&EX(function_state);
@@ -1709,6 +1712,7 @@
                                      }
                                      free_alloca(EX(Ts));
                                      EG(in_execution) =
EX(original_in_execution);
+                                     EG(execute_data_ptr) =
EX(prev_execute_data);
                                      return;
                              }
                              break;
Index: Zend/zend_execute_globals.h =================================================================== RCS file: /repository/Zend/zend_execute_globals.h,v retrieving revision 1.1 diff -u -r1.1 zend_execute_globals.h
--- Zend/zend_execute_globals.h       16 May 2002 04:28:18 -0000
1.1
+++ Zend/zend_execute_globals.h       16 Aug 2002 17:22:02 -0000
@@ -55,9 +55,12 @@
      zend_op *opline;
      zend_function_state function_state;
      zend_function *fbc; /* Function Being Called */
+     zend_class_entry *ce;
      object_info object;
      temp_variable *Ts;
      zend_bool original_in_execution;
+     zend_op_array *op_array;
+     struct  _zend_execute_data *prev_execute_data;
} zend_execute_data; #endif
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php
-- Thies C. Arnzten - Looking for all sorts of freelance work - just ask.. Whishlist: http://www.amazon.de/exec/obidos/wishlist/AB9DY62QWDSZ
-- Thies C. Arnzten - Looking for all sorts of freelance work - just ask..
    Whishlist:  http://www.amazon.de/exec/obidos/wishlist/AB9DY62QWDSZ


« previous php.dev (#87007) next »