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