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
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php