Index: xdebug.c =================================================================== RCS file: /repository/xdebug/xdebug.c,v retrieving revision 1.305 diff -u -r1.305 xdebug.c --- xdebug.c 10 Mar 2006 12:10:26 -0000 1.305 +++ xdebug.c 12 Mar 2006 07:04:36 -0000 @@ -91,24 +91,6 @@ #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 0) int (*old_exit_handler)(ZEND_OPCODE_HANDLER_ARGS); - -static int (*old_jmp_handler)(ZEND_OPCODE_HANDLER_ARGS); -static int (*old_jmpz_handler)(ZEND_OPCODE_HANDLER_ARGS); -static int (*old_is_identical_handler)(ZEND_OPCODE_HANDLER_ARGS); -static int (*old_is_not_identical_handler)(ZEND_OPCODE_HANDLER_ARGS); -static int (*old_is_equal_handler)(ZEND_OPCODE_HANDLER_ARGS); -static int (*old_is_not_equal_handler)(ZEND_OPCODE_HANDLER_ARGS); -static int (*old_is_smaller_handler)(ZEND_OPCODE_HANDLER_ARGS); -static int (*old_is_smaller_or_equal_handler)(ZEND_OPCODE_HANDLER_ARGS); - -static int xdebug_jmp_handler(ZEND_OPCODE_HANDLER_ARGS); -static int xdebug_jmpz_handler(ZEND_OPCODE_HANDLER_ARGS); -static int xdebug_is_identical_handler(ZEND_OPCODE_HANDLER_ARGS); -static int xdebug_is_not_identical_handler(ZEND_OPCODE_HANDLER_ARGS); -static int xdebug_is_equal_handler(ZEND_OPCODE_HANDLER_ARGS); -static int xdebug_is_not_equal_handler(ZEND_OPCODE_HANDLER_ARGS); -static int xdebug_is_smaller_handler(ZEND_OPCODE_HANDLER_ARGS); -static int xdebug_is_smaller_or_equal_handler(ZEND_OPCODE_HANDLER_ARGS); #endif #ifdef ZEND_ENGINE_2 @@ -449,58 +431,6 @@ xdebug_arg_dtor(parts); } -#ifdef ZEND_ENGINE_2 -/* Needed for code coverage as Zend doesn't always add EXT_STMT when expected */ -# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1) || PHP_MAJOR_VERSION >= 6 -#define XDEBUG_OPCODE_OVERRIDE(f) static int xdebug_##f##_handler(ZEND_OPCODE_HANDLER_ARGS) \ -{ \ - if (XG(do_code_coverage)) { \ - zend_op *cur_opcode; \ - int lineno; \ - char *file; \ - int file_len; \ - zend_op_array *op_array = execute_data->op_array; \ -\ - cur_opcode = *EG(opline_ptr); \ - lineno = cur_opcode->lineno; \ -\ - file = op_array->filename; \ - file_len = strlen(file); \ -\ - xdebug_count_line(file, lineno, 0 TSRMLS_CC); \ - } \ - return ZEND_USER_OPCODE_DISPATCH; \ -} -#else -#define XDEBUG_OPCODE_OVERRIDE(f) static int xdebug_##f##_handler(ZEND_OPCODE_HANDLER_ARGS) \ -{ \ - if (XG(do_code_coverage)) { \ - zend_op *cur_opcode; \ - int lineno; \ - char *file; \ - int file_len; \ -\ - cur_opcode = *EG(opline_ptr); \ - lineno = cur_opcode->lineno; \ -\ - file = op_array->filename; \ - file_len = strlen(file); \ -\ - xdebug_count_line(file, lineno, 0 TSRMLS_CC); \ - } \ - return old_##f##_handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \ -} -#endif -XDEBUG_OPCODE_OVERRIDE(jmp) -XDEBUG_OPCODE_OVERRIDE(jmpz) -XDEBUG_OPCODE_OVERRIDE(is_identical) -XDEBUG_OPCODE_OVERRIDE(is_not_identical) -XDEBUG_OPCODE_OVERRIDE(is_equal) -XDEBUG_OPCODE_OVERRIDE(is_not_equal) -XDEBUG_OPCODE_OVERRIDE(is_smaller) -XDEBUG_OPCODE_OVERRIDE(is_smaller_or_equal) -#endif - PHP_MINIT_FUNCTION(xdebug) { @@ -537,35 +467,9 @@ #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 0) old_exit_handler = zend_opcode_handlers[ZEND_EXIT]; zend_opcode_handlers[ZEND_EXIT] = xdebug_exit_handler; - - old_jmp_handler = zend_opcode_handlers[ZEND_JMP]; - old_jmpz_handler = zend_opcode_handlers[ZEND_JMPZ]; - old_is_identical_handler = zend_opcode_handlers[ZEND_IS_IDENTICAL]; - old_is_not_identical_handler = zend_opcode_handlers[ZEND_IS_NOT_IDENTICAL]; - old_is_equal_handler = zend_opcode_handlers[ZEND_IS_EQUAL]; - old_is_not_equal_handler = zend_opcode_handlers[ZEND_IS_NOT_EQUAL]; - old_is_smaller_handler = zend_opcode_handlers[ZEND_IS_SMALLER]; - old_is_smaller_or_equal_handler = zend_opcode_handlers[ZEND_IS_SMALLER_OR_EQUAL]; - - zend_opcode_handlers[ZEND_JMP] = xdebug_jmp_handler; - zend_opcode_handlers[ZEND_JMPZ] = xdebug_jmpz_handler; - zend_opcode_handlers[ZEND_IS_IDENTICAL] = xdebug_is_identical_handler; - zend_opcode_handlers[ZEND_IS_NOT_IDENTICAL] = xdebug_is_not_identical_handler; - zend_opcode_handlers[ZEND_IS_EQUAL] = xdebug_is_equal_handler; - zend_opcode_handlers[ZEND_IS_NOT_EQUAL] = xdebug_is_not_equal_handler; - zend_opcode_handlers[ZEND_IS_SMALLER] = xdebug_is_smaller_handler; - zend_opcode_handlers[ZEND_IS_SMALLER_OR_EQUAL] = xdebug_is_smaller_or_equal_handler; #endif #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1) || PHP_MAJOR_VERSION >= 6 zend_set_user_opcode_handler(ZEND_EXIT, xdebug_exit_handler); - zend_set_user_opcode_handler(ZEND_JMP, xdebug_jmp_handler); - zend_set_user_opcode_handler(ZEND_JMPZ, xdebug_jmpz_handler); - zend_set_user_opcode_handler(ZEND_IS_IDENTICAL, xdebug_is_identical_handler); - zend_set_user_opcode_handler(ZEND_IS_NOT_IDENTICAL, xdebug_is_not_identical_handler); - zend_set_user_opcode_handler(ZEND_IS_EQUAL, xdebug_is_equal_handler); - zend_set_user_opcode_handler(ZEND_IS_NOT_EQUAL, xdebug_is_not_equal_handler); - zend_set_user_opcode_handler(ZEND_IS_SMALLER, xdebug_is_smaller_handler); - zend_set_user_opcode_handler(ZEND_IS_SMALLER_OR_EQUAL, xdebug_is_smaller_or_equal_handler); #endif if (zend_xdebug_initialised == 0) { @@ -1012,10 +916,6 @@ } } - if (XG(do_code_coverage)) { - xdebug_count_line(tmp->filename, tmp->lineno, 0 TSRMLS_CC); - } - if (XG(profiler_aggregate)) { char *func_name = show_fname(tmp->function, 0, 0 TSRMLS_CC); @@ -1213,6 +1113,12 @@ xdebug_llist_element *le; int eval_id = 0; + if (XG(stack) == NULL) { + /* in request shutdown */ + xdebug_old_execute(op_array TSRMLS_CC); + return; + } + if (XG(level) == 0) { /* Set session cookie if requested */ if ( @@ -1401,6 +1303,12 @@ int do_return = (XG(do_trace) && XG(trace_file)); int function_nr = 0; + if (XG(stack) == NULL) { + /* in request shutdown */ + execute_internal(current_execute_data, return_value_used TSRMLS_CC); + return; + } + XG(level)++; if (XG(level) == XG(max_nesting_level)) { php_error(E_ERROR, "Maximum function nesting level of '%ld' reached, aborting!", XG(max_nesting_level)); @@ -2529,6 +2441,24 @@ } +ZEND_DLEXPORT void xdebug_fcall_begin(zend_op_array *op_array) +{ + zend_op *cur_opcode; + int lineno; + char *file; + TSRMLS_FETCH(); + + cur_opcode = *EG(opline_ptr); + lineno = cur_opcode->lineno; + + file = op_array->filename; + + if (XG(do_code_coverage)) { + xdebug_count_line(file, lineno, 0 TSRMLS_CC); + } +} +#define xdebug_fcall_end xdebug_fcall_begin + ZEND_DLEXPORT void xdebug_statement_call(zend_op_array *op_array) { xdebug_llist_element *le; @@ -2674,8 +2604,8 @@ NULL, /* message_handler_func_t */ NULL, /* op_array_handler_func_t */ xdebug_statement_call, /* statement_handler_func_t */ - NULL, /* fcall_begin_handler_func_t */ - NULL, /* fcall_end_handler_func_t */ + xdebug_fcall_begin, /* fcall_begin_handler_func_t */ + xdebug_fcall_end, /* fcall_end_handler_func_t */ NULL, /* op_array_ctor_func_t */ NULL, /* op_array_dtor_func_t */ STANDARD_ZEND_EXTENSION_PROPERTIES Index: xdebug_code_coverage.c =================================================================== RCS file: /repository/xdebug/xdebug_code_coverage.c,v retrieving revision 1.16 diff -u -r1.16 xdebug_code_coverage.c --- xdebug_code_coverage.c 27 Feb 2006 21:00:55 -0000 1.16 +++ xdebug_code_coverage.c 12 Mar 2006 07:04:36 -0000 @@ -45,6 +45,11 @@ xdebug_coverage_line *line; char *sline; + /* lines always > 0 */ + if (lineno < 0) { + return; + } + sline = xdebug_sprintf("%d", lineno); /* Check if the file already exists in the hash */ @@ -77,25 +82,48 @@ xdfree(sline); } -static void prefil_from_opcode(function_stack_entry *fse, char *fn, zend_op opcode TSRMLS_DC) +static void prefil_from_op_array(function_stack_entry *fse, char *fn, zend_op_array *op_array TSRMLS_DC) { - if (opcode.opcode != ZEND_NOP && opcode.opcode != ZEND_EXT_NOP) { - xdebug_count_line(fn, opcode.lineno, 1 TSRMLS_CC); + unsigned int i; + zend_uint size; + + size = op_array->size; +#ifdef ZEND_ENGINE_2 + if (op_array->opcodes[size - 1].opcode == ZEND_HANDLE_EXCEPTION) { + size --; +#endif + if (op_array->opcodes[size - 1].opcode == ZEND_RETURN) { + size --; + /* it's not real php statement */ + if (op_array->opcodes[size - 1].opcode == ZEND_EXT_STMT) { + size --; + } + } +#ifdef ZEND_ENGINE_2 } +#endif + + for (i = 0; i < size; i++) { + switch (op_array->opcodes[i].opcode) { + case ZEND_EXT_STMT: + case ZEND_EXT_FCALL_BEGIN: + case ZEND_EXT_FCALL_END: + xdebug_count_line(fn, op_array->opcodes[i].lineno, 1 TSRMLS_CC); + break; + } + } + } static int prefil_from_function_table(zend_op_array *opa, int num_args, va_list args, zend_hash_key *hash_key) { char *new_filename; - unsigned int i; TSRMLS_FETCH(); new_filename = va_arg(args, char*); if (opa->type == ZEND_USER_FUNCTION) { if (opa->filename && strcmp(opa->filename, new_filename) == 0) { - for (i = 0; i < opa->size; i++) { - prefil_from_opcode(NULL, new_filename, opa->opcodes[i] TSRMLS_CC); - } + prefil_from_op_array(NULL, new_filename, opa TSRMLS_CC); } } @@ -127,12 +155,7 @@ void xdebug_prefil_code_coverage(function_stack_entry *fse, zend_op_array *op_array TSRMLS_DC) { - unsigned int i; - - for (i = 0; i < op_array->size; i++) { - prefil_from_opcode(fse, op_array->filename, op_array->opcodes[i] TSRMLS_CC); - } - + prefil_from_op_array(fse, op_array->filename, op_array TSRMLS_CC); zend_hash_apply_with_arguments(CG(function_table), (apply_func_args_t) prefil_from_function_table, 1, op_array->filename); zend_hash_apply_with_arguments(CG(class_table), (apply_func_args_t) prefil_from_class_table, 1, op_array->filename); } @@ -191,7 +214,7 @@ zval *retval = (zval*) ret; if (line->executable && (line->count == 0)) { - add_index_long(retval, line->lineno, -1); + add_index_long(retval, line->lineno, 0); } else { add_index_long(retval, line->lineno, 1); }