From 07b3ac4ff72a2a862927490365850bb7a9ca7662 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Wed, 15 Oct 2014 22:16:05 +0100 Subject: [PATCH 1/3] Refactor tracing in preparation for another uber cool tracing handler. --- config.m4 | 2 +- config.w32 | 2 +- package.xml | 6 + php_xdebug.h | 6 +- xdebug.c | 50 ++-- xdebug_code_coverage.c | 10 +- xdebug_private.h | 17 ++ xdebug_trace_computerized.c | 251 ++++++++++++++++ xdebug_trace_computerized.h | 30 ++ xdebug_trace_html.c | 134 +++++++++ xdebug_trace_html.h | 30 ++ xdebug_trace_textual.c | 311 ++++++++++++++++++++ xdebug_trace_textual.h | 30 ++ xdebug_tracing.c | 569 ++++-------------------------------- xdebug_tracing.h | 9 +- 15 files changed, 906 insertions(+), 551 deletions(-) create mode 100644 xdebug_trace_computerized.c create mode 100644 xdebug_trace_computerized.h create mode 100644 xdebug_trace_html.c create mode 100644 xdebug_trace_html.h create mode 100644 xdebug_trace_textual.c create mode 100644 xdebug_trace_textual.h diff --git a/config.m4 b/config.m4 index 4d4d95159..7c7ec07a1 100644 --- a/config.m4 +++ b/config.m4 @@ -26,7 +26,7 @@ dnl Check for new current_execute_data field in zend_executor_globals CPPFLAGS=$old_CPPFLAGS - PHP_NEW_EXTENSION(xdebug, xdebug.c xdebug_branch_info.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c xdebug_tracing.c xdebug_var.c xdebug_xml.c usefulstuff.c, $ext_shared,,,,yes) + PHP_NEW_EXTENSION(xdebug, xdebug.c xdebug_branch_info.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c xdebug_tracing.c xdebug_trace_textual.c xdebug_trace_computerized.c xdebug_trace_html.c xdebug_var.c xdebug_xml.c usefulstuff.c, $ext_shared,,,,yes) PHP_SUBST(XDEBUG_SHARED_LIBADD) PHP_ADD_MAKEFILE_FRAGMENT fi diff --git a/config.w32 b/config.w32 index 4b8f8eea2..4dfe1b680 100644 --- a/config.w32 +++ b/config.w32 @@ -4,6 +4,6 @@ ARG_WITH("xdebug", "Xdebug support", "no"); if (PHP_XDEBUG == "yes") { - EXTENSION("xdebug", "xdebug.c xdebug_branch_info.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c xdebug_tracing.c xdebug_var.c xdebug_xml.c usefulstuff.c"); + EXTENSION("xdebug", "xdebug.c xdebug_branch_info.c xdebug_code_coverage.c xdebug_com.c xdebug_compat.c xdebug_handler_dbgp.c xdebug_handlers.c xdebug_llist.c xdebug_hash.c xdebug_private.c xdebug_profiler.c xdebug_set.c xdebug_stack.c xdebug_str.c xdebug_superglobals.c xdebug_tracing.c xdebug_trace_textual.c xdebug_trace_computerized.c xdebug_trace_html.c xdebug_var.c xdebug_xml.c usefulstuff.c"); AC_DEFINE("HAVE_XDEBUG", 1, "Xdebug support"); } diff --git a/package.xml b/package.xml index 3a52f87b1..19fce00eb 100644 --- a/package.xml +++ b/package.xml @@ -177,6 +177,12 @@ Tue, May 08, 2012 - xdebug 2.2.0 + + + + + + diff --git a/php_xdebug.h b/php_xdebug.h index ba5c2d96a..efe8770ca 100644 --- a/php_xdebug.h +++ b/php_xdebug.h @@ -176,7 +176,9 @@ ZEND_BEGIN_MODULE_GLOBALS(xdebug) void (*orig_var_dump_func)(INTERNAL_FUNCTION_PARAMETERS); void (*orig_set_time_limit_func)(INTERNAL_FUNCTION_PARAMETERS); - FILE *trace_file; + xdebug_trace_handler_t *trace_handler; + void *trace_context; + zend_bool do_trace; zend_bool auto_trace; zend_bool trace_enable_trigger; @@ -184,7 +186,7 @@ ZEND_BEGIN_MODULE_GLOBALS(xdebug) char *trace_output_name; long trace_options; long trace_format; - char *tracefile_name; + //char *tracefile_name; char *last_exception_trace; char *last_eval_statement; diff --git a/xdebug.c b/xdebug.c index 8cce2905b..a13ea2d20 100644 --- a/xdebug.c +++ b/xdebug.c @@ -313,7 +313,8 @@ static void php_xdebug_init_globals (zend_xdebug_globals *xg TSRMLS_DC) xg->stack = NULL; xg->level = 0; xg->do_trace = 0; - xg->trace_file = NULL; + xg->trace_handler = NULL; + xg->trace_context = NULL; xg->coverage_enable = 0; xg->previous_filename = ""; xg->previous_file = NULL; @@ -870,8 +871,8 @@ PHP_RINIT_FUNCTION(xdebug) XG(do_code_coverage) = 0; XG(code_coverage) = xdebug_hash_alloc(32, xdebug_coverage_file_dtor); XG(stack) = xdebug_llist_alloc(xdebug_stack_element_dtor); - XG(trace_file) = NULL; - XG(tracefile_name) = NULL; + XG(trace_handler) = NULL; + XG(trace_context) = NULL; XG(profile_file) = NULL; XG(profile_filename) = NULL; XG(prev_memory) = 0; @@ -997,7 +998,7 @@ ZEND_MODULE_POST_ZEND_DEACTIVATE_D(xdebug) xdebug_llist_destroy(XG(stack), NULL); XG(stack) = NULL; - if (XG(do_trace) && XG(trace_file)) { + if (XG(do_trace) && XG(trace_context)) { xdebug_stop_trace(TSRMLS_C); } @@ -1294,7 +1295,7 @@ void xdebug_execute_ex(zend_execute_data *execute_data TSRMLS_DC) zval **dummy; function_stack_entry *fse, *xfse; char *magic_cookie = NULL; - int do_return = (XG(do_trace) && XG(trace_file)); + int do_return = (XG(do_trace) && XG(trace_context)); int function_nr = 0; xdebug_llist_element *le; int clear = 0; @@ -1426,7 +1427,9 @@ void xdebug_execute_ex(zend_execute_data *execute_data TSRMLS_DC) } function_nr = XG(function_count); - xdebug_trace_function_begin(fse, function_nr TSRMLS_CC); + if (XG(do_trace) && XG(trace_context) && (XG(trace_handler)->function_entry)) { + XG(trace_handler)->function_entry(XG(trace_context), fse, function_nr TSRMLS_CC); + } fse->symbol_table = EG(active_symbol_table); #if PHP_VERSION_ID < 50500 @@ -1493,25 +1496,23 @@ void xdebug_execute_ex(zend_execute_data *execute_data TSRMLS_DC) if (XG(profiler_enabled)) { xdebug_profiler_function_user_end(fse, op_array TSRMLS_CC); } - - xdebug_trace_function_end(fse, function_nr TSRMLS_CC); + + if (XG(do_trace) && XG(trace_context) && (XG(trace_handler)->function_exit)) { + XG(trace_handler)->function_exit(XG(trace_context), fse, function_nr TSRMLS_CC); + } /* Store return value in the trace file */ - if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_file)) { + if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_context)) { if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) { - char *t; #if PHP_VERSION_ID >= 50500 if (op_array->fn_flags & ZEND_ACC_GENERATOR) { - t = xdebug_return_trace_stack_generator_retval(fse, (zend_generator *) EG(return_value_ptr_ptr) TSRMLS_CC); + XG(trace_handler)->generator_return_value(XG(trace_context), fse, function_nr, (zend_generator*) EG(return_value_ptr_ptr) TSRMLS_CC); } else { - t = xdebug_return_trace_stack_retval(fse, function_nr, *EG(return_value_ptr_ptr) TSRMLS_CC); + XG(trace_handler)->return_value(XG(trace_context), fse, function_nr, *EG(return_value_ptr_ptr) TSRMLS_CC); } #else - t = xdebug_return_trace_stack_retval(fse, function_nr, *EG(return_value_ptr_ptr) TSRMLS_CC); + XG(trace_handler)->return_value(XG(trace_context), fse, function_nr, *EG(return_value_ptr_ptr) TSRMLS_CC); #endif - fprintf(XG(trace_file), "%s", t); - fflush(XG(trace_file)); - xdfree(t); } } if (clear && *EG(return_value_ptr_ptr)) { @@ -1559,7 +1560,7 @@ void xdebug_execute_internal(zend_execute_data *current_execute_data, struct _ze zend_execute_data *edata = EG(current_execute_data); function_stack_entry *fse; zend_op *cur_opcode; - int do_return = (XG(do_trace) && XG(trace_file)); + int do_return = (XG(do_trace) && XG(trace_context)); int function_nr = 0; int restore_error_handler_situation = 0; @@ -1574,7 +1575,9 @@ void xdebug_execute_internal(zend_execute_data *current_execute_data, struct _ze fse->function.internal = 1; function_nr = XG(function_count); - xdebug_trace_function_begin(fse, function_nr TSRMLS_CC); + if (XG(do_trace) && XG(trace_context) && (XG(trace_handler)->function_entry)) { + XG(trace_handler)->function_entry(XG(trace_context), fse, function_nr TSRMLS_CC); + } /* Check for entry breakpoints */ if (XG(remote_enabled) && XG(breakpoints_allowed)) { @@ -1616,18 +1619,17 @@ void xdebug_execute_internal(zend_execute_data *current_execute_data, struct _ze zend_error_cb = tmp_error_cb; } - xdebug_trace_function_end(fse, function_nr TSRMLS_CC); + if (XG(do_trace) && XG(trace_context) && (XG(trace_handler)->function_exit)) { + XG(trace_handler)->function_exit(XG(trace_context), fse, function_nr TSRMLS_CC); + } /* Store return value in the trace file */ - if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_file) && EG(opline_ptr)) { + if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_context) && EG(opline_ptr)) { cur_opcode = *EG(opline_ptr); if (cur_opcode) { zval *ret = xdebug_zval_ptr(cur_opcode->XDEBUG_TYPE(result), &(cur_opcode->result), current_execute_data TSRMLS_CC); if (ret) { - char* t = xdebug_return_trace_stack_retval(fse, function_nr, ret TSRMLS_CC); - fprintf(XG(trace_file), "%s", t); - fflush(XG(trace_file)); - xdfree(t); + XG(trace_handler)->return_value(XG(trace_context), fse, function_nr, ret TSRMLS_CC); } } } diff --git a/xdebug_code_coverage.c b/xdebug_code_coverage.c index 974b9ed0b..62f000e0d 100644 --- a/xdebug_code_coverage.c +++ b/xdebug_code_coverage.c @@ -292,7 +292,6 @@ static int xdebug_common_assign_dim_handler(char *op, int do_cc, ZEND_OPCODE_HAN zend_op *cur_opcode, *next_opcode; char *full_varname; zval *val = NULL; - char *t; int is_var; function_stack_entry *fse; @@ -308,7 +307,7 @@ static int xdebug_common_assign_dim_handler(char *op, int do_cc, ZEND_OPCODE_HAN xdebug_count_line(file, lineno, 0, 0 TSRMLS_CC); } } - if (XG(do_trace) && XG(trace_file) && XG(collect_assignments)) { + if (XG(do_trace) && XG(trace_context) && XG(collect_assignments)) { full_varname = xdebug_find_var_name(execute_data TSRMLS_CC); if (cur_opcode->opcode >= ZEND_PRE_INC && cur_opcode->opcode <= ZEND_POST_DEC) { @@ -344,11 +343,10 @@ static int xdebug_common_assign_dim_handler(char *op, int do_cc, ZEND_OPCODE_HAN } fse = XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))); - t = xdebug_return_trace_assignment(fse, full_varname, val, op, file, lineno TSRMLS_CC); + if (XG(do_trace) && XG(trace_context) && XG(collect_assignments) && XG(trace_handler)->assignment) { + XG(trace_handler)->assignment(XG(trace_context), fse, full_varname, val, op, file, lineno TSRMLS_CC); + } xdfree(full_varname); - fprintf(XG(trace_file), "%s", t); - fflush(XG(trace_file)); - xdfree(t); } return ZEND_USER_OPCODE_DISPATCH; } diff --git a/xdebug_private.h b/xdebug_private.h index 5aeabbc46..88500dda4 100644 --- a/xdebug_private.h +++ b/xdebug_private.h @@ -206,6 +206,23 @@ function_stack_entry *xdebug_get_stack_head(TSRMLS_D); function_stack_entry *xdebug_get_stack_frame(int nr TSRMLS_DC); function_stack_entry *xdebug_get_stack_tail(TSRMLS_D); +typedef struct +{ + void *(*init)(char *fname, long options TSRMLS_DC); + void (*deinit)(void *ctxt TSRMLS_DC); + void (*write_header)(void *ctxt TSRMLS_DC); + void (*write_footer)(void *ctxt TSRMLS_DC); + char *(*get_filename)(void *ctxt TSRMLS_DC); + void (*function_entry)(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC); + void (*function_exit)(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC); + void (*return_value)(void *ctxt, function_stack_entry *fse, int function_nr, zval *return_value TSRMLS_DC); +#if PHP_VERSION_ID >= 50500 + void (*generator_return_value)(void *ctxt, function_stack_entry *fse, int function_nr, zend_generator *generator TSRMLS_DC); +#endif + void (*assignment)(void *ctxt, function_stack_entry *fse, char *full_varname, zval *value, char *op, char *file, int lineno TSRMLS_DC); +} xdebug_trace_handler_t; + + xdebug_hash* xdebug_used_var_hash_from_llist(xdebug_llist *list); void xdebug_init_debugger(TSRMLS_D); diff --git a/xdebug_trace_computerized.c b/xdebug_trace_computerized.c new file mode 100644 index 000000000..4dc98417b --- /dev/null +++ b/xdebug_trace_computerized.c @@ -0,0 +1,251 @@ +/* + +----------------------------------------------------------------------+ + | Xdebug | + +----------------------------------------------------------------------+ + | Copyright (c) 2002-2014 Derick Rethans | + +----------------------------------------------------------------------+ + | This source file is subject to version 1.0 of the Xdebug license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://xdebug.derickrethans.nl/license.php | + | If you did not receive a copy of the Xdebug license and are unable | + | to obtain it through the world-wide-web, please send a note to | + | xdebug@derickrethans.nl so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + +----------------------------------------------------------------------+ + */ +#include "xdebug_trace_computerized.h" +#include "xdebug_var.h" +#include "ext/standard/php_string.h" + +extern ZEND_DECLARE_MODULE_GLOBALS(xdebug); + +void *xdebug_trace_computerized_init(char *fname, long options TSRMLS_DC) +{ + xdebug_trace_computerized_context *tmp_computerized_context; + char *used_fname; + + tmp_computerized_context = xdmalloc(sizeof(xdebug_trace_computerized_context)); + tmp_computerized_context->trace_file = xdebug_trace_open_file(fname, options, (char**) &used_fname TSRMLS_CC); + tmp_computerized_context->trace_filename = used_fname; + + return tmp_computerized_context; +} + +void xdebug_trace_computerized_deinit(void *ctxt TSRMLS_DC) +{ + xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt; + + fclose(context->trace_file); + context->trace_file = NULL; + xdfree(context->trace_filename); + + xdfree(context); +} + +void xdebug_trace_computerized_write_header(void *ctxt TSRMLS_DC) +{ + xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt; + char *str_time; + + fprintf(context->trace_file, "Version: %s\n", XDEBUG_VERSION); + fprintf(context->trace_file, "File format: 4\n"); + + str_time = xdebug_get_time(); + fprintf(context->trace_file, "TRACE START [%s]\n", str_time); + fflush(context->trace_file); + xdfree(str_time); +} + +void xdebug_trace_computerized_write_footer(void *ctxt TSRMLS_DC) +{ + xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt; + char *str_time; + double u_time; + char *tmp; + + u_time = xdebug_get_utime(); + tmp = xdebug_sprintf("\t\t\t%f\t", u_time - XG(start_time)); + fprintf(context->trace_file, "%s", tmp); + xdfree(tmp); +#if HAVE_PHP_MEMORY_USAGE + fprintf(context->trace_file, "%lu", XG_MEMORY_USAGE()); +#else + fprintf(context->trace_file, ""); +#endif + fprintf(context->trace_file, "\n"); + str_time = xdebug_get_time(); + + fprintf(context->trace_file, "TRACE END [%s]\n\n", str_time); + fflush(context->trace_file); + xdfree(str_time); +} + +char *xdebug_trace_computerized_get_filename(void *ctxt TSRMLS_DC) +{ + xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt; + + return context->trace_filename; +} + +static char *render_variable(zval *var, int type TSRMLS_DC) +{ + char *tmp_value = NULL; + + switch (XG(collect_params)) { + case 1: /* synopsis */ + case 2: + tmp_value = xdebug_get_zval_synopsis(var, 0, NULL); + break; + case 3: /* full */ + case 4: /* full (with var) */ + default: + tmp_value = xdebug_get_zval_value(var, 0, NULL); + break; + case 5: /* serialized */ + tmp_value = xdebug_get_zval_value_serialized(var, 0, NULL TSRMLS_CC); + break; + } + + return tmp_value; +} + + +void xdebug_trace_computerized_function_entry(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC) +{ + xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt; + char *tmp_name; + xdebug_str str = {0, 0, NULL}; + + xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->level), 1); + xdebug_str_add(&str, xdebug_sprintf("%d\t", function_nr), 1); + + tmp_name = xdebug_show_fname(fse->function, 0, 0 TSRMLS_CC); + + xdebug_str_add(&str, "0\t", 0); + xdebug_str_add(&str, xdebug_sprintf("%f\t", fse->time - XG(start_time)), 1); +#if HAVE_PHP_MEMORY_USAGE + xdebug_str_add(&str, xdebug_sprintf("%lu\t", fse->memory), 1); +#else + xdebug_str_add(&str, "\t", 0); +#endif + xdebug_str_add(&str, xdebug_sprintf("%s\t", tmp_name), 1); + xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->user_defined == XDEBUG_EXTERNAL ? 1 : 0), 1); + xdfree(tmp_name); + + if (fse->include_filename) { + if (fse->function.type == XFUNC_EVAL) { + int tmp_len; + + char *escaped; + escaped = php_addcslashes(fse->include_filename, strlen(fse->include_filename), &tmp_len, 0, "'\\\0..\37", 6 TSRMLS_CC); + xdebug_str_add(&str, xdebug_sprintf("'%s'", escaped), 1); + efree(escaped); + } else { + xdebug_str_add(&str, fse->include_filename, 0); + } + } + + /* Filename and Lineno (9, 10) */ + xdebug_str_add(&str, xdebug_sprintf("\t%s\t%d", fse->filename, fse->lineno), 1); + + + if (XG(collect_params) > 0) { + unsigned int j = 0; /* Counter */ + + /* Nr of arguments (11) */ + xdebug_str_add(&str, xdebug_sprintf("\t%d", fse->varc), 1); + + /* Arguments (12-...) */ + for (j = 0; j < fse->varc; j++) { + char *tmp_value; + + xdebug_str_addl(&str, "\t", 1, 0); + + if (fse->var[j].is_variadic) { + xdebug_str_addl(&str, "...\t", 4, 0); + } + + if (fse->var[j].name && XG(collect_params) == 4) { + xdebug_str_add(&str, xdebug_sprintf("$%s = ", fse->var[j].name), 1); + } + + tmp_value = render_variable(fse->var[j].addr, XG(collect_params) TSRMLS_CC); + + if (tmp_value) { + xdebug_str_add(&str, tmp_value, 1); + } else { + xdebug_str_add(&str, "???", 0); + } + } + } + + /* Trailing \n */ + xdebug_str_add(&str, "\n", 0); + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + xdfree(str.d); +} + +void xdebug_trace_computerized_function_exit(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC) +{ + xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt; + xdebug_str str = {0, 0, NULL}; + + xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->level), 1); + xdebug_str_add(&str, xdebug_sprintf("%d\t", function_nr), 1); + + xdebug_str_add(&str, "1\t", 0); + xdebug_str_add(&str, xdebug_sprintf("%f\t", xdebug_get_utime() - XG(start_time)), 1); +#if HAVE_PHP_MEMORY_USAGE + xdebug_str_add(&str, xdebug_sprintf("%lu\n", XG_MEMORY_USAGE()), 1); +#else + xdebug_str_add(&str, "\n", 0); +#endif + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + xdfree(str.d); +} + +void xdebug_trace_computerized_function_return_value(void *ctxt, function_stack_entry *fse, int function_nr, zval *return_value TSRMLS_DC) +{ + xdebug_trace_computerized_context *context = (xdebug_trace_computerized_context*) ctxt; + xdebug_str str = {0, 0, NULL}; + char *tmp_value = NULL; + + xdebug_str_add(&str, xdebug_sprintf("%d\t", fse->level), 1); + xdebug_str_add(&str, xdebug_sprintf("%d\t", function_nr), 1); + xdebug_str_add(&str, "R\t\t\t", 0); + + tmp_value = render_variable(return_value, XG(collect_params) TSRMLS_CC); + + if (tmp_value) { + xdebug_str_add(&str, tmp_value, 1); + } else { + xdebug_str_add(&str, "???", 0); + } + xdebug_str_addl(&str, "\n", 2, 0); + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + xdfree(str.d); +} + +xdebug_trace_handler_t xdebug_trace_handler_computerized = +{ + xdebug_trace_computerized_init, + xdebug_trace_computerized_deinit, + xdebug_trace_computerized_write_header, + xdebug_trace_computerized_write_footer, + xdebug_trace_computerized_get_filename, + xdebug_trace_computerized_function_entry, + xdebug_trace_computerized_function_exit, + xdebug_trace_computerized_function_return_value, +#if PHP_VERSION_ID >= 50500 + NULL /* xdebug_trace_computerized_generator_return_value */, +#endif + NULL /* xdebug_trace_computerized_assignment */ +}; diff --git a/xdebug_trace_computerized.h b/xdebug_trace_computerized.h new file mode 100644 index 000000000..b5ef2d534 --- /dev/null +++ b/xdebug_trace_computerized.h @@ -0,0 +1,30 @@ +/* + +----------------------------------------------------------------------+ + | Xdebug | + +----------------------------------------------------------------------+ + | Copyright (c) 2002-2014 Derick Rethans | + +----------------------------------------------------------------------+ + | This source file is subject to version 1.0 of the Xdebug license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://xdebug.derickrethans.nl/license.php | + | If you did not receive a copy of the Xdebug license and are unable | + | to obtain it through the world-wide-web, please send a note to | + | xdebug@derickrethans.nl so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + +----------------------------------------------------------------------+ + */ +#ifndef XDEBUG_TRACE_COMPUTERIZED_H +#define XDEBUG_TRACE_COMPUTERIZED_H + +#include "xdebug_tracing.h" + +typedef struct _xdebug_trace_computerized_context +{ + FILE *trace_file; + char *trace_filename; +} xdebug_trace_computerized_context; + +extern xdebug_trace_handler_t xdebug_trace_handler_computerized; +#endif diff --git a/xdebug_trace_html.c b/xdebug_trace_html.c new file mode 100644 index 000000000..12a1483a7 --- /dev/null +++ b/xdebug_trace_html.c @@ -0,0 +1,134 @@ +/* + +----------------------------------------------------------------------+ + | Xdebug | + +----------------------------------------------------------------------+ + | Copyright (c) 2002-2014 Derick Rethans | + +----------------------------------------------------------------------+ + | This source file is subject to version 1.0 of the Xdebug license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://xdebug.derickrethans.nl/license.php | + | If you did not receive a copy of the Xdebug license and are unable | + | to obtain it through the world-wide-web, please send a note to | + | xdebug@derickrethans.nl so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + +----------------------------------------------------------------------+ + */ +#include "xdebug_trace_html.h" +#include "xdebug_var.h" + +extern ZEND_DECLARE_MODULE_GLOBALS(xdebug); + +void *xdebug_trace_html_init(char *fname, long options TSRMLS_DC) +{ + xdebug_trace_html_context *tmp_html_context; + char *used_fname; + + tmp_html_context = xdmalloc(sizeof(xdebug_trace_html_context)); + tmp_html_context->trace_file = xdebug_trace_open_file(fname, options, (char**) &used_fname); + tmp_html_context->trace_filename = used_fname; + + return tmp_html_context; +} + +void xdebug_trace_html_deinit(void *ctxt TSRMLS_DC) +{ + xdebug_trace_html_context *context = (xdebug_trace_html_context*) ctxt; + + fclose(context->trace_file); + context->trace_file = NULL; + xdfree(context->trace_filename); + + xdfree(context); +} + +void xdebug_trace_html_write_header(void *ctxt TSRMLS_DC) +{ + xdebug_trace_html_context *context = (xdebug_trace_html_context*) ctxt; + + fprintf(context->trace_file, "\n"); + fprintf(context->trace_file, "\t"); +#if HAVE_PHP_MEMORY_USAGE + fprintf(context->trace_file, ""); +#endif + fprintf(context->trace_file, "\n"); + fflush(context->trace_file); +} + +void xdebug_trace_html_write_footer(void *ctxt TSRMLS_DC) +{ + xdebug_trace_html_context *context = (xdebug_trace_html_context*) ctxt; + + fprintf(context->trace_file, "
#TimeMemFunctionLocation
\n"); + fflush(context->trace_file); +} + +char *xdebug_trace_html_get_filename(void *ctxt TSRMLS_DC) +{ + xdebug_trace_html_context *context = (xdebug_trace_html_context*) ctxt; + + return context->trace_filename; +} + +void xdebug_trace_html_function_entry(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC) +{ + xdebug_trace_html_context *context = (xdebug_trace_html_context*) ctxt; + char *tmp_name; + unsigned int j; + xdebug_str str = {0, 0, NULL}; + + xdebug_str_add(&str, "\t", 0); + xdebug_str_add(&str, xdebug_sprintf("%d", function_nr), 1); + xdebug_str_add(&str, xdebug_sprintf("%0.6f", fse->time - XG(start_time)), 1); +#if HAVE_PHP_MEMORY_USAGE + xdebug_str_add(&str, xdebug_sprintf("%lu", fse->memory), 1); +#endif + xdebug_str_add(&str, "", 0); + for (j = 0; j < fse->level - 1; j++) { + xdebug_str_add(&str, "   ", 0); + } + xdebug_str_add(&str, "->", 0); + + tmp_name = xdebug_show_fname(fse->function, 0, 0 TSRMLS_CC); + xdebug_str_add(&str, xdebug_sprintf("%s(", tmp_name), 1); + xdfree(tmp_name); + + if (fse->include_filename) { + if (fse->function.type == XFUNC_EVAL) { + char *joined; + xdebug_arg *parts = (xdebug_arg*) xdmalloc(sizeof(xdebug_arg)); + + xdebug_arg_init(parts); + xdebug_explode("\n", fse->include_filename, parts, 99999); + joined = xdebug_join("
", parts, 0, 99999); + xdebug_arg_dtor(parts); + + xdebug_str_add(&str, xdebug_sprintf("'%s'", joined), 1); + xdfree(joined); + } else { + xdebug_str_add(&str, fse->include_filename, 0); + } + } + + xdebug_str_add(&str, xdebug_sprintf(")%s:%d", fse->filename, fse->lineno), 1); + xdebug_str_add(&str, "\n", 0); + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + xdfree(str.d); +} + +xdebug_trace_handler_t xdebug_trace_handler_html = +{ + xdebug_trace_html_init, + xdebug_trace_html_deinit, + xdebug_trace_html_write_header, + xdebug_trace_html_write_footer, + xdebug_trace_html_get_filename, + xdebug_trace_html_function_entry, + NULL /* xdebug_trace_html_function_exit */, + NULL /* xdebug_trace_html_function_return_value */, + NULL /* xdebug_trace_html_generator_return_value */, + NULL, /* xdebug_trace_html_assignment */ +}; diff --git a/xdebug_trace_html.h b/xdebug_trace_html.h new file mode 100644 index 000000000..52d506bcd --- /dev/null +++ b/xdebug_trace_html.h @@ -0,0 +1,30 @@ +/* + +----------------------------------------------------------------------+ + | Xdebug | + +----------------------------------------------------------------------+ + | Copyright (c) 2002-2014 Derick Rethans | + +----------------------------------------------------------------------+ + | This source file is subject to version 1.0 of the Xdebug license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://xdebug.derickrethans.nl/license.php | + | If you did not receive a copy of the Xdebug license and are unable | + | to obtain it through the world-wide-web, please send a note to | + | xdebug@derickrethans.nl so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + +----------------------------------------------------------------------+ + */ +#ifndef XDEBUG_TRACE_HTML_H +#define XDEBUG_TRACE_HTML_H + +#include "xdebug_tracing.h" + +typedef struct _xdebug_trace_html_context +{ + FILE *trace_file; + char *trace_filename; +} xdebug_trace_html_context; + +extern xdebug_trace_handler_t xdebug_trace_handler_html; +#endif diff --git a/xdebug_trace_textual.c b/xdebug_trace_textual.c new file mode 100644 index 000000000..b46ef81bb --- /dev/null +++ b/xdebug_trace_textual.c @@ -0,0 +1,311 @@ +/* + +----------------------------------------------------------------------+ + | Xdebug | + +----------------------------------------------------------------------+ + | Copyright (c) 2002-2014 Derick Rethans | + +----------------------------------------------------------------------+ + | This source file is subject to version 1.0 of the Xdebug license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://xdebug.derickrethans.nl/license.php | + | If you did not receive a copy of the Xdebug license and are unable | + | to obtain it through the world-wide-web, please send a note to | + | xdebug@derickrethans.nl so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + +----------------------------------------------------------------------+ + */ +#include "xdebug_tracing.h" +#include "xdebug_trace_textual.h" +#include "xdebug_var.h" +#include "ext/standard/php_string.h" + +extern ZEND_DECLARE_MODULE_GLOBALS(xdebug); + +void *xdebug_trace_textual_init(char *fname, long options TSRMLS_DC) +{ + xdebug_trace_textual_context *tmp_textual_context; + char *used_fname; + + tmp_textual_context = xdmalloc(sizeof(xdebug_trace_textual_context)); + tmp_textual_context->trace_file = xdebug_trace_open_file(fname, options, (char**) &used_fname TSRMLS_CC); + tmp_textual_context->trace_filename = used_fname; + + return tmp_textual_context; +} + +void xdebug_trace_textual_deinit(void *ctxt TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + + fclose(context->trace_file); + context->trace_file = NULL; + xdfree(context->trace_filename); + + xdfree(context); +} + +void xdebug_trace_textual_write_header(void *ctxt TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + char *str_time; + + str_time = xdebug_get_time(); + fprintf(context->trace_file, "TRACE START [%s]\n", str_time); + fflush(context->trace_file); + xdfree(str_time); +} + +void xdebug_trace_textual_write_footer(void *ctxt TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + char *str_time; + double u_time; + char *tmp; + + u_time = xdebug_get_utime(); + tmp = xdebug_sprintf("%10.4f ", u_time - XG(start_time)); + fprintf(context->trace_file, "%s", tmp); + xdfree(tmp); +#if HAVE_PHP_MEMORY_USAGE + fprintf(context->trace_file, "%10zu", XG_MEMORY_USAGE()); +#else + fprintf(context->trace_file, "%10u", 0); +#endif + fprintf(context->trace_file, "\n"); + str_time = xdebug_get_time(); + fprintf(context->trace_file, "TRACE END [%s]\n\n", str_time); + fflush(context->trace_file); + xdfree(str_time); +} + +char *xdebug_trace_textual_get_filename(void *ctxt TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + + return context->trace_filename; +} + +void xdebug_trace_textual_function_entry(void *ctxt, function_stack_entry *fse, int function_nr TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + int c = 0; /* Comma flag */ + unsigned int j = 0; /* Counter */ + char *tmp_name; + xdebug_str str = {0, 0, NULL}; + + tmp_name = xdebug_show_fname(fse->function, 0, 0 TSRMLS_CC); + + xdebug_str_add(&str, xdebug_sprintf("%10.4f ", fse->time - XG(start_time)), 1); + xdebug_str_add(&str, xdebug_sprintf("%10lu ", fse->memory), 1); + if (XG(show_mem_delta)) { + xdebug_str_add(&str, xdebug_sprintf("%+8ld ", fse->memory - fse->prev_memory), 1); + } + for (j = 0; j < fse->level; j++) { + xdebug_str_addl(&str, " ", 2, 0); + } + xdebug_str_add(&str, xdebug_sprintf("-> %s(", tmp_name), 1); + + xdfree(tmp_name); + + /* Printing vars */ + if (XG(collect_params) > 0) { + int variadic_opened = 0; + int variadic_count = 0; + + for (j = 0; j < fse->varc; j++) { + char *tmp_value; + + if (c) { + xdebug_str_addl(&str, ", ", 2, 0); + } else { + c = 1; + } + + if (fse->var[j].is_variadic && fse->var[j].addr) { + xdebug_str_add(&str, "...", 0); + variadic_opened = 1; + } + + if (fse->var[j].name && XG(collect_params) == 4) { + xdebug_str_add(&str, xdebug_sprintf("$%s = ", fse->var[j].name), 1); + } + + if (fse->var[j].is_variadic && fse->var[j].addr) { + xdebug_str_add(&str, "variadic(", 0); + } + + if (variadic_opened && XG(collect_params) != 5) { + xdebug_str_add(&str, xdebug_sprintf("%d => ", variadic_count++), 1); + } + + switch (XG(collect_params)) { + case 1: /* synopsis */ + case 2: + tmp_value = xdebug_get_zval_synopsis(fse->var[j].addr, 0, NULL); + break; + case 3: /* full */ + case 4: /* full (with var) */ + default: + tmp_value = xdebug_get_zval_value(fse->var[j].addr, 0, NULL); + break; + case 5: /* serialized */ + tmp_value = xdebug_get_zval_value_serialized(fse->var[j].addr, 0, NULL TSRMLS_CC); + break; + } + if (tmp_value) { + xdebug_str_add(&str, tmp_value, 1); + } else { + xdebug_str_add(&str, "???", 0); + } + } + + if (variadic_opened) { + xdebug_str_add(&str, ")", 0); + } + } + + if (fse->include_filename) { + if (fse->function.type == XFUNC_EVAL) { + int tmp_len; + + char *escaped; + escaped = php_addcslashes(fse->include_filename, strlen(fse->include_filename), &tmp_len, 0, "'\\\0..\37", 6 TSRMLS_CC); + xdebug_str_add(&str, xdebug_sprintf("'%s'", escaped), 1); + efree(escaped); + } else { + xdebug_str_add(&str, fse->include_filename, 0); + } + } + + xdebug_str_add(&str, xdebug_sprintf(") %s:%d\n", fse->filename, fse->lineno), 1); + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + + xdfree(str.d); +} + +/* Used for normal return values, and generator return values */ +static void xdebug_return_trace_stack_common(xdebug_str *str, function_stack_entry *fse TSRMLS_DC) +{ + unsigned int j = 0; /* Counter */ + + xdebug_str_add(str, xdebug_sprintf("%10.4f ", xdebug_get_utime() - XG(start_time)), 1); +#if HAVE_PHP_MEMORY_USAGE + xdebug_str_add(str, xdebug_sprintf("%10lu ", XG_MEMORY_USAGE()), 1); +#endif + + if (XG(show_mem_delta)) { + xdebug_str_addl(str, " ", 8, 0); + } + for (j = 0; j < fse->level; j++) { + xdebug_str_addl(str, " ", 2, 0); + } + xdebug_str_addl(str, " >=> ", 5, 0); +} + + +void xdebug_trace_textual_function_return_value(void *ctxt, function_stack_entry *fse, int function_nr, zval *return_value TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + xdebug_str str = {0, 0, NULL}; + char *tmp_value; + + xdebug_return_trace_stack_common(&str, fse TSRMLS_CC); + + tmp_value = xdebug_get_zval_value(return_value, 0, NULL); + if (tmp_value) { + xdebug_str_add(&str, tmp_value, 1); + } + xdebug_str_addl(&str, "\n", 2, 0); + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + + xdfree(str.d); +} + +#if PHP_VERSION_ID >= 50500 +void xdebug_trace_textual_generator_return_value(void *ctxt, function_stack_entry *fse, int function_nr, zend_generator *generator TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + xdebug_str str = {0, 0, NULL}; + char *tmp_value = NULL; + + /* Generator key */ + tmp_value = xdebug_get_zval_value(generator->key, 0, NULL); + if (tmp_value) { + xdebug_return_trace_stack_common(&str, fse TSRMLS_CC); + + xdebug_str_addl(&str, "(", 1, 0); + xdebug_str_add(&str, tmp_value, 1); + xdebug_str_addl(&str, " => ", 4, 0); + + tmp_value = xdebug_get_zval_value(generator->value, 0, NULL); + if (tmp_value) { + xdebug_str_add(&str, tmp_value, 1); + } + xdebug_str_addl(&str, ")", 1, 0); + xdebug_str_addl(&str, "\n", 2, 0); + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + + xdfree(str.d); + } +} +#endif + +void xdebug_trace_textual_assignment(void *ctxt, function_stack_entry *fse, char *full_varname, zval *retval, char *op, char *filename, int lineno TSRMLS_DC) +{ + xdebug_trace_textual_context *context = (xdebug_trace_textual_context*) ctxt; + unsigned int j = 0; + xdebug_str str = {0, 0, NULL}; + char *tmp_value; + + xdebug_str_addl(&str, " ", 20, 0); + if (XG(show_mem_delta)) { + xdebug_str_addl(&str, " ", 8, 0); + } + for (j = 0; j <= fse->level; j++) { + xdebug_str_addl(&str, " ", 2, 0); + } + xdebug_str_addl(&str, " => ", 6, 0); + + xdebug_str_add(&str, full_varname, 0); + + if (op[0] != '\0' ) { /* pre/post inc/dec ops are special */ + xdebug_str_add(&str, xdebug_sprintf(" %s ", op), 1); + + tmp_value = xdebug_get_zval_value(retval, 0, NULL); + + if (tmp_value) { + xdebug_str_add(&str, tmp_value, 1); + } else { + xdebug_str_addl(&str, "NULL", 4, 0); + } + } + xdebug_str_add(&str, xdebug_sprintf(" %s:%d\n", filename, lineno), 1); + + fprintf(context->trace_file, "%s", str.d); + fflush(context->trace_file); + + xdfree(str.d); +} + +xdebug_trace_handler_t xdebug_trace_handler_textual = +{ + xdebug_trace_textual_init, + xdebug_trace_textual_deinit, + xdebug_trace_textual_write_header, + xdebug_trace_textual_write_footer, + xdebug_trace_textual_get_filename, + xdebug_trace_textual_function_entry, + NULL /*xdebug_trace_textual_function_exit */, + xdebug_trace_textual_function_return_value, +#if PHP_VERSION_ID >= 50500 + xdebug_trace_textual_generator_return_value, +#endif + xdebug_trace_textual_assignment +}; diff --git a/xdebug_trace_textual.h b/xdebug_trace_textual.h new file mode 100644 index 000000000..a59234b75 --- /dev/null +++ b/xdebug_trace_textual.h @@ -0,0 +1,30 @@ +/* + +----------------------------------------------------------------------+ + | Xdebug | + +----------------------------------------------------------------------+ + | Copyright (c) 2002-2014 Derick Rethans | + +----------------------------------------------------------------------+ + | This source file is subject to version 1.0 of the Xdebug license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://xdebug.derickrethans.nl/license.php | + | If you did not receive a copy of the Xdebug license and are unable | + | to obtain it through the world-wide-web, please send a note to | + | xdebug@derickrethans.nl so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Derick Rethans | + +----------------------------------------------------------------------+ + */ +#ifndef XDEBUG_TRACE_TEXTUAL_H +#define XDEBUG_TRACE_TEXTUAL_H + +#include "xdebug_tracing.h" + +typedef struct _xdebug_trace_textual_context +{ + FILE *trace_file; + char *trace_filename; +} xdebug_trace_textual_context; + +extern xdebug_trace_handler_t xdebug_trace_handler_textual; +#endif diff --git a/xdebug_tracing.c b/xdebug_tracing.c index 02c9fc182..a5109b6b2 100644 --- a/xdebug_tracing.c +++ b/xdebug_tracing.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Xdebug | +----------------------------------------------------------------------+ - | Copyright (c) 2002-2013 Derick Rethans | + | Copyright (c) 2002-2014 Derick Rethans | +----------------------------------------------------------------------+ | This source file is subject to version 1.0 of the Xdebug license, | | that is bundled with this package in the file LICENSE, and is | @@ -12,7 +12,7 @@ | to obtain it through the world-wide-web, please send a note to | | xdebug@derickrethans.nl so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Derick Rethans | + | Authors: Derick Rethans | +----------------------------------------------------------------------+ */ #include "php_xdebug.h" @@ -22,449 +22,85 @@ #include "xdebug_var.h" #include "ext/standard/php_string.h" -ZEND_EXTERN_MODULE_GLOBALS(xdebug) - -static char* return_trace_stack_frame_begin(function_stack_entry* i, int fnr TSRMLS_DC); -static char* return_trace_stack_frame_end(function_stack_entry* i, int fnr TSRMLS_DC); - -void xdebug_trace_function_begin(function_stack_entry *fse, int function_nr TSRMLS_DC) -{ - if (XG(do_trace) && XG(trace_file)) { - char *t = return_trace_stack_frame_begin(fse, function_nr TSRMLS_CC); - if (fprintf(XG(trace_file), "%s", t) < 0) { - fclose(XG(trace_file)); - XG(trace_file) = NULL; - } else { - fflush(XG(trace_file)); - } - xdfree(t); - } -} - -void xdebug_trace_function_end(function_stack_entry *fse, int function_nr TSRMLS_DC) -{ - if (XG(do_trace) && XG(trace_file)) { - char *t = return_trace_stack_frame_end(fse, function_nr TSRMLS_CC); - if (fprintf(XG(trace_file), "%s", t) < 0) { - fclose(XG(trace_file)); - XG(trace_file) = NULL; - } else { - fflush(XG(trace_file)); - } - xdfree(t); - } -} - - -char* xdebug_return_trace_assignment(function_stack_entry *i, char *varname, zval *retval, char *op, char *filename, int lineno TSRMLS_DC) -{ - unsigned int j = 0; - xdebug_str str = {0, 0, NULL}; - char *tmp_value; - - if (XG(trace_format) != 0) { - return xdstrdup(""); - } - - xdebug_str_addl(&str, " ", 20, 0); - if (XG(show_mem_delta)) { - xdebug_str_addl(&str, " ", 8, 0); - } - for (j = 0; j <= i->level; j++) { - xdebug_str_addl(&str, " ", 2, 0); - } - xdebug_str_addl(&str, " => ", 6, 0); - - xdebug_str_add(&str, varname, 0); - - if (op[0] != '\0' ) { /* pre/post inc/dec ops are special */ - xdebug_str_add(&str, xdebug_sprintf(" %s ", op), 1); - - tmp_value = xdebug_get_zval_value(retval, 0, NULL); - - if (tmp_value) { - xdebug_str_add(&str, tmp_value, 1); - } else { - xdebug_str_addl(&str, "NULL", 4, 0); - } - } - xdebug_str_add(&str, xdebug_sprintf(" %s:%d\n", filename, lineno), 1); - - return str.d; -} - -static void xdebug_return_trace_stack_common(xdebug_str *str, function_stack_entry *i TSRMLS_DC) -{ - unsigned int j = 0; /* Counter */ - - xdebug_str_add(str, xdebug_sprintf("%10.4f ", xdebug_get_utime() - XG(start_time)), 1); -#if HAVE_PHP_MEMORY_USAGE - xdebug_str_add(str, xdebug_sprintf("%10lu ", XG_MEMORY_USAGE()), 1); -#endif +#include "xdebug_tracing.h" +#include "xdebug_trace_textual.h" +#include "xdebug_trace_computerized.h" +#include "xdebug_trace_html.h" - if (XG(show_mem_delta)) { - xdebug_str_addl(str, " ", 8, 0); - } - for (j = 0; j < i->level; j++) { - xdebug_str_addl(str, " ", 2, 0); - } - xdebug_str_addl(str, " >=> ", 5, 0); -} +ZEND_EXTERN_MODULE_GLOBALS(xdebug) -static char* return_trace_stack_retval_normal(function_stack_entry* i, zval* retval TSRMLS_DC) +xdebug_trace_handler_t *xdebug_select_trace_handler(int options TSRMLS_DC) { - xdebug_str str = {0, 0, NULL}; - char *tmp_value; - - xdebug_return_trace_stack_common(&str, i TSRMLS_CC); + xdebug_trace_handler_t *tmp; - tmp_value = xdebug_get_zval_value(retval, 0, NULL); - if (tmp_value) { - xdebug_str_add(&str, tmp_value, 1); + switch (XG(trace_format)) { + case 0: tmp = &xdebug_trace_handler_textual; break; + case 1: tmp = &xdebug_trace_handler_computerized; break; + case 2: tmp = &xdebug_trace_handler_html; break; } - xdebug_str_addl(&str, "\n", 2, 0); - - return str.d; -} -static char *render_variable(zval *var, int type TSRMLS_DC) -{ - char *tmp_value = NULL; - - switch (XG(collect_params)) { - case 1: /* synopsis */ - case 2: - tmp_value = xdebug_get_zval_synopsis(var, 0, NULL); - break; - case 3: /* full */ - case 4: /* full (with var) */ - default: - tmp_value = xdebug_get_zval_value(var, 0, NULL); - break; - case 5: /* serialized */ - tmp_value = xdebug_get_zval_value_serialized(var, 0, NULL TSRMLS_CC); - break; + if (options & XDEBUG_TRACE_OPTION_COMPUTERIZED) { + tmp = &xdebug_trace_handler_computerized; } - - return tmp_value; -} - -static char* return_trace_stack_retval_computerized(function_stack_entry* i, int fnr, zval* retval TSRMLS_DC) -{ - xdebug_str str = {0, 0, NULL}; - char *tmp_value = NULL; - - xdebug_str_add(&str, xdebug_sprintf("%d\t", i->level), 1); - xdebug_str_add(&str, xdebug_sprintf("%d\t", fnr), 1); - xdebug_str_add(&str, "R\t\t\t", 0); - - tmp_value = render_variable(retval, XG(collect_params) TSRMLS_CC); - - if (tmp_value) { - xdebug_str_add(&str, tmp_value, 1); - } else { - xdebug_str_add(&str, "???", 0); + if (options & XDEBUG_TRACE_OPTION_HTML) { + tmp = &xdebug_trace_handler_html; } - xdebug_str_addl(&str, "\n", 2, 0); - return str.d; + return tmp; } -char* xdebug_return_trace_stack_retval(function_stack_entry* i, int fnr, zval* retval TSRMLS_DC) +FILE *xdebug_trace_open_file(char *fname, long options, char **used_fname TSRMLS_DC) { - switch (XG(trace_format)) { - case 0: - return return_trace_stack_retval_normal(i, retval TSRMLS_CC); - case 1: - return return_trace_stack_retval_computerized(i, fnr, retval TSRMLS_CC); - default: - return xdstrdup(""); - } -} - -#if PHP_VERSION_ID >= 50500 -char* xdebug_return_trace_stack_generator_retval(function_stack_entry* i, zend_generator* generator TSRMLS_DC) -{ - xdebug_str str = {0, 0, NULL}; - char *tmp_value = NULL; - - if (XG(trace_format) != 0) { - return xdstrdup(""); - } - - /* Generator key */ - tmp_value = xdebug_get_zval_value(generator->key, 0, NULL); - if (tmp_value) { - xdebug_return_trace_stack_common(&str, i TSRMLS_CC); - - xdebug_str_addl(&str, "(", 1, 0); - xdebug_str_add(&str, tmp_value, 1); - xdebug_str_addl(&str, " => ", 4, 0); + FILE *file; + char *filename; - tmp_value = xdebug_get_zval_value(generator->value, 0, NULL); - if (tmp_value) { - xdebug_str_add(&str, tmp_value, 1); - } - xdebug_str_addl(&str, ")", 1, 0); - xdebug_str_addl(&str, "\n", 2, 0); - return str.d; + if (fname && strlen(fname)) { + filename = xdstrdup(fname); } else { - return xdstrdup(""); - } -} -#endif - -static char* return_trace_stack_frame_begin_normal(function_stack_entry* i TSRMLS_DC) -{ - int c = 0; /* Comma flag */ - unsigned int j = 0; /* Counter */ - char *tmp_name; - xdebug_str str = {0, 0, NULL}; - - tmp_name = xdebug_show_fname(i->function, 0, 0 TSRMLS_CC); - - xdebug_str_add(&str, xdebug_sprintf("%10.4f ", i->time - XG(start_time)), 1); - xdebug_str_add(&str, xdebug_sprintf("%10lu ", i->memory), 1); - if (XG(show_mem_delta)) { - xdebug_str_add(&str, xdebug_sprintf("%+8ld ", i->memory - i->prev_memory), 1); - } - for (j = 0; j < i->level; j++) { - xdebug_str_addl(&str, " ", 2, 0); - } - xdebug_str_add(&str, xdebug_sprintf("-> %s(", tmp_name), 1); - - xdfree(tmp_name); - - /* Printing vars */ - if (XG(collect_params) > 0) { - int variadic_opened = 0; - int variadic_count = 0; - - for (j = 0; j < i->varc; j++) { - char *tmp_value; - - if (c) { - xdebug_str_addl(&str, ", ", 2, 0); - } else { - c = 1; - } - - if (i->var[j].is_variadic && i->var[j].addr) { - xdebug_str_add(&str, "...", 0); - variadic_opened = 1; - } - - if (i->var[j].name && XG(collect_params) == 4) { - xdebug_str_add(&str, xdebug_sprintf("$%s = ", i->var[j].name), 1); - } - - if (i->var[j].is_variadic && i->var[j].addr) { - xdebug_str_add(&str, "variadic(", 0); - } - - if (variadic_opened && XG(collect_params) != 5) { - xdebug_str_add(&str, xdebug_sprintf("%d => ", variadic_count++), 1); - } - - switch (XG(collect_params)) { - case 1: /* synopsis */ - case 2: - tmp_value = xdebug_get_zval_synopsis(i->var[j].addr, 0, NULL); - break; - case 3: /* full */ - case 4: /* full (with var) */ - default: - tmp_value = xdebug_get_zval_value(i->var[j].addr, 0, NULL); - break; - case 5: /* serialized */ - tmp_value = xdebug_get_zval_value_serialized(i->var[j].addr, 0, NULL TSRMLS_CC); - break; - } - if (tmp_value) { - xdebug_str_add(&str, tmp_value, 1); - } else { - xdebug_str_add(&str, "???", 0); - } - } - - if (variadic_opened) { - xdebug_str_add(&str, ")", 0); + if (!strlen(XG(trace_output_name)) || + xdebug_format_output_filename(&fname, XG(trace_output_name), NULL) <= 0 + ) { + /* Invalid or empty xdebug.trace_output_name */ + return NULL; } - } - - if (i->include_filename) { - if (i->function.type == XFUNC_EVAL) { - int tmp_len; - - char *escaped; - escaped = php_addcslashes(i->include_filename, strlen(i->include_filename), &tmp_len, 0, "'\\\0..\37", 6 TSRMLS_CC); - xdebug_str_add(&str, xdebug_sprintf("'%s'", escaped), 1); - efree(escaped); + if (IS_SLASH(XG(trace_output_dir)[strlen(XG(trace_output_dir)) - 1])) { + filename = xdebug_sprintf("%s%s", XG(trace_output_dir), fname); } else { - xdebug_str_add(&str, i->include_filename, 0); + filename = xdebug_sprintf("%s%c%s", XG(trace_output_dir), DEFAULT_SLASH, fname); } + xdfree(fname); } - - xdebug_str_add(&str, xdebug_sprintf(") %s:%d\n", i->filename, i->lineno), 1); - - return str.d; -} - -#define return_trace_stack_frame_begin_computerized(i,f) return_trace_stack_frame_computerized((i), (f), 0 TSRMLS_CC) -#define return_trace_stack_frame_end_computerized(i,f) return_trace_stack_frame_computerized((i), (f), 1 TSRMLS_CC) - -static char* return_trace_stack_frame_computerized(function_stack_entry* i, int fnr, int whence TSRMLS_DC) -{ - char *tmp_name; - xdebug_str str = {0, 0, NULL}; - - xdebug_str_add(&str, xdebug_sprintf("%d\t", i->level), 1); - xdebug_str_add(&str, xdebug_sprintf("%d\t", fnr), 1); - if (whence == 0) { /* start */ - tmp_name = xdebug_show_fname(i->function, 0, 0 TSRMLS_CC); - - xdebug_str_add(&str, "0\t", 0); - xdebug_str_add(&str, xdebug_sprintf("%f\t", i->time - XG(start_time)), 1); -#if HAVE_PHP_MEMORY_USAGE - xdebug_str_add(&str, xdebug_sprintf("%lu\t", i->memory), 1); -#else - xdebug_str_add(&str, "\t", 0); -#endif - xdebug_str_add(&str, xdebug_sprintf("%s\t", tmp_name), 1); - xdebug_str_add(&str, xdebug_sprintf("%d\t", i->user_defined == XDEBUG_EXTERNAL ? 1 : 0), 1); - xdfree(tmp_name); - - if (i->include_filename) { - if (i->function.type == XFUNC_EVAL) { - int tmp_len; - - char *escaped; - escaped = php_addcslashes(i->include_filename, strlen(i->include_filename), &tmp_len, 0, "'\\\0..\37", 6 TSRMLS_CC); - xdebug_str_add(&str, xdebug_sprintf("'%s'", escaped), 1); - efree(escaped); - } else { - xdebug_str_add(&str, i->include_filename, 0); - } - } - - /* Filename and Lineno (9, 10) */ - xdebug_str_add(&str, xdebug_sprintf("\t%s\t%d", i->filename, i->lineno), 1); - - - if (XG(collect_params) > 0) { - unsigned int j = 0; /* Counter */ - - /* Nr of arguments (11) */ - xdebug_str_add(&str, xdebug_sprintf("\t%d", i->varc), 1); - - /* Arguments (12-...) */ - for (j = 0; j < i->varc; j++) { - char *tmp_value; - - xdebug_str_addl(&str, "\t", 1, 0); - - if (i->var[j].is_variadic) { - xdebug_str_addl(&str, "...\t", 4, 0); - } - - if (i->var[j].name && XG(collect_params) == 4) { - xdebug_str_add(&str, xdebug_sprintf("$%s = ", i->var[j].name), 1); - } - - tmp_value = render_variable(i->var[j].addr, XG(collect_params) TSRMLS_CC); - - if (tmp_value) { - xdebug_str_add(&str, tmp_value, 1); - } else { - xdebug_str_add(&str, "???", 0); - } - } - } - - /* Trailing \n */ - xdebug_str_add(&str, "\n", 0); - - } else if (whence == 1) { /* end */ - xdebug_str_add(&str, "1\t", 0); - xdebug_str_add(&str, xdebug_sprintf("%f\t", xdebug_get_utime() - XG(start_time)), 1); -#if HAVE_PHP_MEMORY_USAGE - xdebug_str_add(&str, xdebug_sprintf("%lu\n", XG_MEMORY_USAGE()), 1); -#else - xdebug_str_add(&str, "\n", 0); -#endif + if (options & XDEBUG_TRACE_OPTION_APPEND) { + file = xdebug_fopen(filename, "a", (options & XDEBUG_TRACE_OPTION_NAKED_FILENAME) ? NULL : "xt", used_fname); + } else { + file = xdebug_fopen(filename, "w", (options & XDEBUG_TRACE_OPTION_NAKED_FILENAME) ? NULL : "xt", used_fname); } + xdfree(filename); - return str.d; + return file; } -static char* return_trace_stack_frame_begin_html(function_stack_entry* i, int fnr TSRMLS_DC) +char* xdebug_start_trace(char* fname, long options TSRMLS_DC) { - char *tmp_name; - unsigned int j; - xdebug_str str = {0, 0, NULL}; - - xdebug_str_add(&str, "\t", 0); - xdebug_str_add(&str, xdebug_sprintf("%d", fnr), 1); - xdebug_str_add(&str, xdebug_sprintf("%0.6f", i->time - XG(start_time)), 1); -#if HAVE_PHP_MEMORY_USAGE - xdebug_str_add(&str, xdebug_sprintf("%lu", i->memory), 1); -#endif - xdebug_str_add(&str, "", 0); - for (j = 0; j < i->level - 1; j++) { - xdebug_str_add(&str, "   ", 0); - } - xdebug_str_add(&str, "->", 0); - - tmp_name = xdebug_show_fname(i->function, 0, 0 TSRMLS_CC); - xdebug_str_add(&str, xdebug_sprintf("%s(", tmp_name), 1); - xdfree(tmp_name); - - if (i->include_filename) { - if (i->function.type == XFUNC_EVAL) { - char *joined; - xdebug_arg *parts = (xdebug_arg*) xdmalloc(sizeof(xdebug_arg)); + XG(trace_handler) = xdebug_select_trace_handler(options TSRMLS_CC); + XG(trace_context) = (void*) XG(trace_handler)->init(fname, options TSRMLS_CC); - xdebug_arg_init(parts); - xdebug_explode("\n", i->include_filename, parts, 99999); - joined = xdebug_join("
", parts, 0, 99999); - xdebug_arg_dtor(parts); - - xdebug_str_add(&str, xdebug_sprintf("'%s'", joined), 1); - xdfree(joined); - } else { - xdebug_str_add(&str, i->include_filename, 0); - } + if (XG(trace_context)) { + XG(do_trace) = 1; + XG(trace_handler)->write_header(XG(trace_context) TSRMLS_CC); + return xdstrdup(XG(trace_handler)->get_filename(XG(trace_context) TSRMLS_CC)); } - xdebug_str_add(&str, xdebug_sprintf(")%s:%d", i->filename, i->lineno), 1); - xdebug_str_add(&str, "\n", 0); - - return str.d; -} - - -static char* return_trace_stack_frame_begin(function_stack_entry* i, int fnr TSRMLS_DC) -{ - switch (XG(trace_format)) { - case 0: - return return_trace_stack_frame_begin_normal(i TSRMLS_CC); - case 1: - return return_trace_stack_frame_begin_computerized(i, fnr); - case 2: - return return_trace_stack_frame_begin_html(i, fnr TSRMLS_CC); - default: - return xdstrdup(""); - } + return NULL; } - -static char* return_trace_stack_frame_end(function_stack_entry* i, int fnr TSRMLS_DC) +void xdebug_stop_trace(TSRMLS_D) { - switch (XG(trace_format)) { - case 1: - return return_trace_stack_frame_end_computerized(i, fnr); - default: - return xdstrdup(""); + XG(do_trace) = 0; + if (XG(trace_context)) { + XG(trace_handler)->write_footer(XG(trace_context) TSRMLS_CC); + XG(trace_handler)->deinit(XG(trace_context) TSRMLS_CC); + XG(trace_context) = NULL; } } @@ -497,105 +133,10 @@ PHP_FUNCTION(xdebug_start_trace) } } -char* xdebug_start_trace(char* fname, long options TSRMLS_DC) -{ - char *str_time; - char *filename; - char *tmp_fname = NULL; - - if (fname && strlen(fname)) { - filename = xdstrdup(fname); - } else { - if (!strlen(XG(trace_output_name)) || - xdebug_format_output_filename(&fname, XG(trace_output_name), NULL) <= 0 - ) { - /* Invalid or empty xdebug.trace_output_name */ - return NULL; - } - if (IS_SLASH(XG(trace_output_dir)[strlen(XG(trace_output_dir)) - 1])) { - filename = xdebug_sprintf("%s%s", XG(trace_output_dir), fname); - } else { - filename = xdebug_sprintf("%s%c%s", XG(trace_output_dir), DEFAULT_SLASH, fname); - } - xdfree(fname); - } - if (options & XDEBUG_TRACE_OPTION_APPEND) { - XG(trace_file) = xdebug_fopen(filename, "a", (options & XDEBUG_TRACE_OPTION_NAKED_FILENAME) ? NULL : "xt", (char**) &tmp_fname); - } else { - XG(trace_file) = xdebug_fopen(filename, "w", (options & XDEBUG_TRACE_OPTION_NAKED_FILENAME) ? NULL : "xt", (char**) &tmp_fname); - } - xdfree(filename); - if (options & XDEBUG_TRACE_OPTION_COMPUTERIZED) { - XG(trace_format) = 1; - } - if (options & XDEBUG_TRACE_OPTION_HTML) { - XG(trace_format) = 2; - } - if (XG(trace_file)) { - if (XG(trace_format) == 1) { - fprintf(XG(trace_file), "Version: %s\n", XDEBUG_VERSION); - fprintf(XG(trace_file), "File format: 4\n"); - } - if (XG(trace_format) == 0 || XG(trace_format) == 1) { - str_time = xdebug_get_time(); - fprintf(XG(trace_file), "TRACE START [%s]\n", str_time); - xdfree(str_time); - } - if (XG(trace_format) == 2) { - fprintf(XG(trace_file), "\n"); - fprintf(XG(trace_file), "\t"); -#if HAVE_PHP_MEMORY_USAGE - fprintf(XG(trace_file), ""); -#endif - fprintf(XG(trace_file), "\n"); - } - XG(do_trace) = 1; - XG(tracefile_name) = tmp_fname; - return xdstrdup(XG(tracefile_name)); - } - return NULL; -} - -void xdebug_stop_trace(TSRMLS_D) -{ - char *str_time; - double u_time; - char *tmp; - - XG(do_trace) = 0; - if (XG(trace_file)) { - if (XG(trace_format) == 0 || XG(trace_format) == 1) { - u_time = xdebug_get_utime(); - tmp = xdebug_sprintf(XG(trace_format) == 0 ? "%10.4f " : "\t\t\t%f\t", u_time - XG(start_time)); - fprintf(XG(trace_file), "%s", tmp); - xdfree(tmp); -#if HAVE_PHP_MEMORY_USAGE - fprintf(XG(trace_file), XG(trace_format) == 0 ? "%10zu" : "%lu", XG_MEMORY_USAGE()); -#else - fprintf(XG(trace_file), XG(trace_format) == 0 ? "%10u" : "", 0); -#endif - fprintf(XG(trace_file), "\n"); - str_time = xdebug_get_time(); - fprintf(XG(trace_file), "TRACE END [%s]\n\n", str_time); - xdfree(str_time); - } - if (XG(trace_format) == 2) { - fprintf(XG(trace_file), "
#TimeMemFunctionLocation
\n"); - } - - fclose(XG(trace_file)); - XG(trace_file) = NULL; - } - if (XG(tracefile_name)) { - xdfree(XG(tracefile_name)); - XG(tracefile_name) = NULL; - } -} - PHP_FUNCTION(xdebug_stop_trace) { if (XG(do_trace) == 1) { - RETVAL_STRING(XG(tracefile_name), 1); + RETVAL_STRING(XG(trace_handler)->get_filename(XG(trace_context)), 1); xdebug_stop_trace(TSRMLS_C); } else { RETVAL_FALSE; @@ -605,8 +146,8 @@ PHP_FUNCTION(xdebug_stop_trace) PHP_FUNCTION(xdebug_get_tracefile_name) { - if (XG(tracefile_name)) { - RETURN_STRING(XG(tracefile_name), 1); + if (XG(trace_handler)->get_filename) { + RETURN_STRING(XG(trace_handler)->get_filename(XG(trace_context)), 1); } else { RETURN_FALSE; } diff --git a/xdebug_tracing.h b/xdebug_tracing.h index 6b7c68234..6078a12a3 100644 --- a/xdebug_tracing.h +++ b/xdebug_tracing.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Xdebug | +----------------------------------------------------------------------+ - | Copyright (c) 2002-2013 Derick Rethans | + | Copyright (c) 2002-2014 Derick Rethans | +----------------------------------------------------------------------+ | This source file is subject to version 1.0 of the Xdebug license, | | that is bundled with this package in the file LICENSE, and is | @@ -12,18 +12,21 @@ | to obtain it through the world-wide-web, please send a note to | | xdebug@derickrethans.nl so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Derick Rethans | + | Authors: Derick Rethans | +----------------------------------------------------------------------+ */ - #ifndef XDEBUG_TRACING_H #define XDEBUG_TRACING_H +#include "php.h" +#include "php_xdebug.h" + char* xdebug_return_trace_stack_retval(function_stack_entry* i, int fnr, zval* retval TSRMLS_DC); #if PHP_VERSION_ID >= 50500 char* xdebug_return_trace_stack_generator_retval(function_stack_entry* i, zend_generator* generator TSRMLS_DC); #endif char* xdebug_return_trace_assignment(function_stack_entry *i, char *varname, zval *retval, char *op, char *file, int fileno TSRMLS_DC); +FILE *xdebug_trace_open_file(char *fname, long options, char **used_fname TSRMLS_DC); void xdebug_trace_function_begin(function_stack_entry *fse, int function_nr TSRMLS_DC); void xdebug_trace_function_end(function_stack_entry *fse, int function_nr TSRMLS_DC); From a78f522ee01fadf0c6acc483c92fdd8ae7c2b343 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Thu, 16 Oct 2014 13:41:54 +0100 Subject: [PATCH 2/3] Misc test case fixes and memory issues. Already part of Xdebug proper too, but needed it in here to be able to proceed. --- tests/bug00538-2.phpt | 2 +- xdebug.c | 2 +- xdebug_compat.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/bug00538-2.phpt b/tests/bug00538-2.phpt index 03b729cc3..063e2aa3f 100644 --- a/tests/bug00538-2.phpt +++ b/tests/bug00538-2.phpt @@ -48,7 +48,7 @@ array(2) { ["params"]=> array(3) { ["param1"]=> - string(%d) "'%sxdebug'" + string(%d) "'%s'" ["param2"]=> string(16) "'candena\\a\\nb'" ["param3"]=> diff --git a/xdebug.c b/xdebug.c index a13ea2d20..2b4c59c96 100644 --- a/xdebug.c +++ b/xdebug.c @@ -1624,7 +1624,7 @@ void xdebug_execute_internal(zend_execute_data *current_execute_data, struct _ze } /* Store return value in the trace file */ - if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_context) && EG(opline_ptr)) { + if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_context) && EG(opline_ptr) && current_execute_data->opline) { cur_opcode = *EG(opline_ptr); if (cur_opcode) { zval *ret = xdebug_zval_ptr(cur_opcode->XDEBUG_TYPE(result), &(cur_opcode->result), current_execute_data TSRMLS_CC); diff --git a/xdebug_compat.c b/xdebug_compat.c index 5f4e40e41..51f42ee69 100644 --- a/xdebug_compat.c +++ b/xdebug_compat.c @@ -75,6 +75,7 @@ zval *xdebug_zval_ptr(int op_type, XDEBUG_ZNODE *node, zend_execute_data *zdata if (!zdata->opline) { return NULL; } + switch (op_type & 0x0F) { case IS_CONST: #if PHP_VERSION_ID >= 50399 From a8589821227d88fef8c7e583a44ec1c26f62bdd0 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Fri, 24 Oct 2014 12:31:07 -0400 Subject: [PATCH 3/3] ZTS issues and test fixes --- tests/stacktrace_variadic_html_0.phpt | 18 +++++++++--------- tests/stacktrace_variadic_html_1.phpt | 18 +++++++++--------- tests/stacktrace_variadic_html_2.phpt | 18 +++++++++--------- tests/stacktrace_variadic_html_3.phpt | 18 +++++++++--------- tests/stacktrace_variadic_html_4.phpt | 18 +++++++++--------- tests/stacktrace_variadic_html_5.phpt | 18 +++++++++--------- tests/xdebug_get_function_stack_variadic.phpt | 6 +++--- xdebug.c | 11 +++++++++-- xdebug_branch_info.c | 6 +++--- xdebug_branch_info.h | 4 ++-- xdebug_code_coverage.c | 17 +++++++++-------- xdebug_code_coverage.h | 2 +- xdebug_stack.c | 2 +- xdebug_trace_html.c | 6 ++++-- xdebug_tracing.c | 6 +++--- 15 files changed, 89 insertions(+), 79 deletions(-) diff --git a/tests/stacktrace_variadic_html_0.phpt b/tests/stacktrace_variadic_html_0.phpt index 16b224c12..57c0e7844 100644 --- a/tests/stacktrace_variadic_html_0.phpt +++ b/tests/stacktrace_variadic_html_0.phpt @@ -32,28 +32,28 @@ foo( "foo", "bar", 3.1415 ); ( ! ) Notice: notice in %sstacktrace_variadic_html_0.php on line 4 Call Stack #TimeMemoryFunctionLocation -1%f%d{main}( )../stacktrace_variadic_html_0.php:0 -2%f%dfoo( )../stacktrace_variadic_html_0.php:7 +1%f%d{main}( ).../stacktrace_variadic_html_0.php:0 +2%f%dfoo( ).../stacktrace_variadic_html_0.php:7 3%f%dtrigger_error -( )../stacktrace_variadic_html_0.php:4 +( ).../stacktrace_variadic_html_0.php:4
- - + + +( )
( ! ) Notice: notice in %sstacktrace_variadic_html_0.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_0.php:0
2%f%dfoo( )../stacktrace_variadic_html_0.php:8
1%f%d{main}( ).../stacktrace_variadic_html_0.php:0
2%f%dfoo( ).../stacktrace_variadic_html_0.php:8
3%f%dtrigger_error -( )../stacktrace_variadic_html_0.php:4
.../stacktrace_variadic_html_0.php:4

- - + + +( )
( ! ) Notice: notice in %sstacktrace_variadic_html_0.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_0.php:0
2%f%dfoo( )../stacktrace_variadic_html_0.php:9
1%f%d{main}( ).../stacktrace_variadic_html_0.php:0
2%f%dfoo( ).../stacktrace_variadic_html_0.php:9
3%f%dtrigger_error -( )../stacktrace_variadic_html_0.php:4
.../stacktrace_variadic_html_0.php:4
diff --git a/tests/stacktrace_variadic_html_1.phpt b/tests/stacktrace_variadic_html_1.phpt index 03096fcdf..0df64bafa 100644 --- a/tests/stacktrace_variadic_html_1.phpt +++ b/tests/stacktrace_variadic_html_1.phpt @@ -32,28 +32,28 @@ foo( "foo", "bar", 3.1415 ); ( ! ) Notice: notice in %sstacktrace_variadic_html_1.php on line 4 Call Stack #TimeMemoryFunctionLocation -1%f%d{main}( )../stacktrace_variadic_html_1.php:0 -2%f%dfoo( long, ??? )../stacktrace_variadic_html_1.php:7 +1%f%d{main}( ).../stacktrace_variadic_html_1.php:0 +2%f%dfoo( long, ??? ).../stacktrace_variadic_html_1.php:7 3%f%dtrigger_error -( string(6) )../stacktrace_variadic_html_1.php:4 +( string(6) ).../stacktrace_variadic_html_1.php:4
- - + + +( string(6) )
( ! ) Notice: notice in %sstacktrace_variadic_html_1.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_1.php:0
2%f%dfoo( long, ...variadic(bool) )../stacktrace_variadic_html_1.php:8
1%f%d{main}( ).../stacktrace_variadic_html_1.php:0
2%f%dfoo( long, ...variadic(bool) ).../stacktrace_variadic_html_1.php:8
3%f%dtrigger_error -( string(6) )../stacktrace_variadic_html_1.php:4
.../stacktrace_variadic_html_1.php:4

- - + + +( string(6) )
( ! ) Notice: notice in %sstacktrace_variadic_html_1.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_1.php:0
2%f%dfoo( string(3), ...variadic(string(3), double) )../stacktrace_variadic_html_1.php:9
1%f%d{main}( ).../stacktrace_variadic_html_1.php:0
2%f%dfoo( string(3), ...variadic(string(3), double) ).../stacktrace_variadic_html_1.php:9
3%f%dtrigger_error -( string(6) )../stacktrace_variadic_html_1.php:4
.../stacktrace_variadic_html_1.php:4
diff --git a/tests/stacktrace_variadic_html_2.phpt b/tests/stacktrace_variadic_html_2.phpt index bcf1c3b60..9c71c2929 100644 --- a/tests/stacktrace_variadic_html_2.phpt +++ b/tests/stacktrace_variadic_html_2.phpt @@ -32,28 +32,28 @@ foo( "foo", "bar", 3.1415 ); ( ! ) Notice: notice in %sstacktrace_variadic_html_2.php on line 4 Call Stack #TimeMemoryFunctionLocation -1%f%d{main}( )../stacktrace_variadic_html_2.php:0 -2%f%dfoo( long, ??? )../stacktrace_variadic_html_2.php:7 +1%f%d{main}( ).../stacktrace_variadic_html_2.php:0 +2%f%dfoo( long, ??? ).../stacktrace_variadic_html_2.php:7 3%f%dtrigger_error -( string(6) )../stacktrace_variadic_html_2.php:4 +( string(6) ).../stacktrace_variadic_html_2.php:4
- - + + +( string(6) )
( ! ) Notice: notice in %sstacktrace_variadic_html_2.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_2.php:0
2%f%dfoo( long, ...variadic(bool) )../stacktrace_variadic_html_2.php:8
1%f%d{main}( ).../stacktrace_variadic_html_2.php:0
2%f%dfoo( long, ...variadic(bool) ).../stacktrace_variadic_html_2.php:8
3%f%dtrigger_error -( string(6) )../stacktrace_variadic_html_2.php:4
.../stacktrace_variadic_html_2.php:4

- - + + +( string(6) )
( ! ) Notice: notice in %sstacktrace_variadic_html_2.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_2.php:0
2%f%dfoo( string(3), ...variadic(string(3), double) )../stacktrace_variadic_html_2.php:9
1%f%d{main}( ).../stacktrace_variadic_html_2.php:0
2%f%dfoo( string(3), ...variadic(string(3), double) ).../stacktrace_variadic_html_2.php:9
3%f%dtrigger_error -( string(6) )../stacktrace_variadic_html_2.php:4
.../stacktrace_variadic_html_2.php:4
diff --git a/tests/stacktrace_variadic_html_3.phpt b/tests/stacktrace_variadic_html_3.phpt index b5de17813..9590ab661 100644 --- a/tests/stacktrace_variadic_html_3.phpt +++ b/tests/stacktrace_variadic_html_3.phpt @@ -32,28 +32,28 @@ foo( "foo", "bar", 3.1415 ); ( ! ) Notice: notice in %sstacktrace_variadic_html_3.php on line 4 Call Stack #TimeMemoryFunctionLocation -1%f%d{main}( )../stacktrace_variadic_html_3.php:0 -2%f%dfoo( 42, ??? )../stacktrace_variadic_html_3.php:7 +1%f%d{main}( ).../stacktrace_variadic_html_3.php:0 +2%f%dfoo( 42, ??? ).../stacktrace_variadic_html_3.php:7 3%f%dtrigger_error -( 'notice' )../stacktrace_variadic_html_3.php:4 +( 'notice' ).../stacktrace_variadic_html_3.php:4
- - + + +( 'notice' )
( ! ) Notice: notice in %sstacktrace_variadic_html_3.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_3.php:0
2%f%dfoo( 1, ...variadic(FALSE) )../stacktrace_variadic_html_3.php:8
1%f%d{main}( ).../stacktrace_variadic_html_3.php:0
2%f%dfoo( 1, ...variadic(FALSE) ).../stacktrace_variadic_html_3.php:8
3%f%dtrigger_error -( 'notice' )../stacktrace_variadic_html_3.php:4
.../stacktrace_variadic_html_3.php:4

- - + + +( 'notice' )
( ! ) Notice: notice in %sstacktrace_variadic_html_3.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_3.php:0
2%f%dfoo( 'foo', ...variadic('bar', 3.1415) )../stacktrace_variadic_html_3.php:9
1%f%d{main}( ).../stacktrace_variadic_html_3.php:0
2%f%dfoo( 'foo', ...variadic('bar', 3.1415) ).../stacktrace_variadic_html_3.php:9
3%f%dtrigger_error -( 'notice' )../stacktrace_variadic_html_3.php:4
.../stacktrace_variadic_html_3.php:4
diff --git a/tests/stacktrace_variadic_html_4.phpt b/tests/stacktrace_variadic_html_4.phpt index afd09c964..d057ea896 100644 --- a/tests/stacktrace_variadic_html_4.phpt +++ b/tests/stacktrace_variadic_html_4.phpt @@ -32,28 +32,28 @@ foo( "foo", "bar", 3.1415 ); ( ! ) Notice: notice in %sstacktrace_variadic_html_4.php on line 4 Call Stack #TimeMemoryFunctionLocation -1%f%d{main}( )../stacktrace_variadic_html_4.php:0 -2%f%dfoo( $a = 42, $b = ??? )../stacktrace_variadic_html_4.php:7 +1%f%d{main}( ).../stacktrace_variadic_html_4.php:0 +2%f%dfoo( $a = 42, $b = ??? ).../stacktrace_variadic_html_4.php:7 3%f%dtrigger_error -( 'notice' )../stacktrace_variadic_html_4.php:4 +( 'notice' ).../stacktrace_variadic_html_4.php:4
- - + + +( 'notice' )
( ! ) Notice: notice in %sstacktrace_variadic_html_4.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_4.php:0
2%f%dfoo( $a = 1, ...$b = variadic(FALSE) )../stacktrace_variadic_html_4.php:8
1%f%d{main}( ).../stacktrace_variadic_html_4.php:0
2%f%dfoo( $a = 1, ...$b = variadic(FALSE) ).../stacktrace_variadic_html_4.php:8
3%f%dtrigger_error -( 'notice' )../stacktrace_variadic_html_4.php:4
.../stacktrace_variadic_html_4.php:4

- - + + +( 'notice' )
( ! ) Notice: notice in %sstacktrace_variadic_html_4.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_4.php:0
2%f%dfoo( $a = 'foo', ...$b = variadic('bar', 3.1415) )../stacktrace_variadic_html_4.php:9
1%f%d{main}( ).../stacktrace_variadic_html_4.php:0
2%f%dfoo( $a = 'foo', ...$b = variadic('bar', 3.1415) ).../stacktrace_variadic_html_4.php:9
3%f%dtrigger_error -( 'notice' )../stacktrace_variadic_html_4.php:4
.../stacktrace_variadic_html_4.php:4
diff --git a/tests/stacktrace_variadic_html_5.phpt b/tests/stacktrace_variadic_html_5.phpt index 333a955e2..88475de4e 100644 --- a/tests/stacktrace_variadic_html_5.phpt +++ b/tests/stacktrace_variadic_html_5.phpt @@ -32,28 +32,28 @@ foo( "foo", "bar", 3.1415 ); ( ! ) Notice: notice in %sstacktrace_variadic_html_5.php on line 4 Call Stack #TimeMemoryFunctionLocation -1%f%d{main}( )../stacktrace_variadic_html_5.php:0 -2%f%dfoo( aTo0Mjs=, ??? )../stacktrace_variadic_html_5.php:7 +1%f%d{main}( ).../stacktrace_variadic_html_5.php:0 +2%f%dfoo( aTo0Mjs=, ??? ).../stacktrace_variadic_html_5.php:7 3%f%dtrigger_error -( czo2OiJub3RpY2UiOw== )../stacktrace_variadic_html_5.php:4 +( czo2OiJub3RpY2UiOw== ).../stacktrace_variadic_html_5.php:4
- - + + +( czo2OiJub3RpY2UiOw== )
( ! ) Notice: notice in %sstacktrace_variadic_html_5.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_5.php:0
2%f%dfoo( aToxOw==, ...variadic(YjowOw==) )../stacktrace_variadic_html_5.php:8
1%f%d{main}( ).../stacktrace_variadic_html_5.php:0
2%f%dfoo( aToxOw==, ...variadic(YjowOw==) ).../stacktrace_variadic_html_5.php:8
3%f%dtrigger_error -( czo2OiJub3RpY2UiOw== )../stacktrace_variadic_html_5.php:4
.../stacktrace_variadic_html_5.php:4

- - + + +( czo2OiJub3RpY2UiOw== )
( ! ) Notice: notice in %sstacktrace_variadic_html_5.php on line 4
Call Stack
#TimeMemoryFunctionLocation
1%f%d{main}( )../stacktrace_variadic_html_5.php:0
2%f%dfoo( czozOiJmb28iOw==, ...variadic(czozOiJiYXIiOw==, ZDozLjE0MTUwMDAwMDAwMDAwMDI7) )../stacktrace_variadic_html_5.php:9
1%f%d{main}( ).../stacktrace_variadic_html_5.php:0
2%f%dfoo( czozOiJmb28iOw==, ...variadic(czozOiJiYXIiOw==, ZDozLjE0MTUwMDAwMDAwMDAwMDI7) ).../stacktrace_variadic_html_5.php:9
3%f%dtrigger_error -( czo2OiJub3RpY2UiOw== )../stacktrace_variadic_html_5.php:4
.../stacktrace_variadic_html_5.php:4
diff --git a/tests/xdebug_get_function_stack_variadic.phpt b/tests/xdebug_get_function_stack_variadic.phpt index 7b850eb48..2691a3d0c 100644 --- a/tests/xdebug_get_function_stack_variadic.phpt +++ b/tests/xdebug_get_function_stack_variadic.phpt @@ -34,7 +34,7 @@ array(4) { 'function' => string(3) "foo" 'file' => - string(80) "%sxdebug_get_function_stack_variadic.php" + string(%d) "%sxdebug_get_function_stack_variadic.php" 'line' => int(8) 'params' => @@ -49,7 +49,7 @@ array(4) { 'function' => string(3) "foo" 'file' => - string(80) "%sxdebug_get_function_stack_variadic.php" + string(%d) "%sxdebug_get_function_stack_variadic.php" 'line' => int(9) 'params' => @@ -67,7 +67,7 @@ array(4) { 'function' => string(3) "foo" 'file' => - string(80) "%sxdebug_get_function_stack_variadic.php" + string(%d) "%sxdebug_get_function_stack_variadic.php" 'line' => int(10) 'params' => diff --git a/xdebug.c b/xdebug.c index 2b4c59c96..13f44c7c4 100644 --- a/xdebug.c +++ b/xdebug.c @@ -331,6 +331,8 @@ static void php_xdebug_init_globals (zend_xdebug_globals *xg TSRMLS_DC) xg->output_is_tty = OUTPUT_NOT_CHECKED; xg->stdout_mode = 0; xg->in_at = 0; + xg->active_execute_data = NULL; + xg->active_op_array = NULL; xdebug_llist_init(&xg->server, xdebug_superglobals_dump_dtor); xdebug_llist_init(&xg->get, xdebug_superglobals_dump_dtor); @@ -471,7 +473,7 @@ static int xdebug_silence_handler(ZEND_OPCODE_HANDLER_ARGS) zend_op *cur_opcode = *EG(opline_ptr); if (XG(do_code_coverage)) { - xdebug_print_opcode_info('S', execute_data, cur_opcode); + xdebug_print_opcode_info('S', execute_data, cur_opcode TSRMLS_CC); } if (XG(do_scream)) { execute_data->opline++; @@ -491,7 +493,7 @@ static int xdebug_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS) if (XG(do_code_coverage)) { zend_op *cur_opcode = *EG(opline_ptr); - xdebug_print_opcode_info('I', execute_data, cur_opcode); + xdebug_print_opcode_info('I', execute_data, cur_opcode TSRMLS_CC); } #if PHP_VERSION_ID >= 50399 if (opline->extended_value == ZEND_EVAL) { @@ -710,6 +712,11 @@ PHP_MINIT_FUNCTION(xdebug) for (i = 0; i < 256; i++) { if (zend_get_user_opcode_handler(i) == NULL) { +#if ZTS + if (i == ZEND_HANDLE_EXCEPTION) { + continue; + } +#endif zend_set_user_opcode_handler(i, xdebug_check_branch_entry_handler); } } diff --git a/xdebug_branch_info.c b/xdebug_branch_info.c index b0e172775..160253cf7 100644 --- a/xdebug_branch_info.c +++ b/xdebug_branch_info.c @@ -134,7 +134,7 @@ static void xdebug_path_info_add_path(xdebug_path_info *path_info, xdebug_path * path_info->paths_count++; } -void xdebug_path_info_add_path_for_level(xdebug_path_info *path_info, xdebug_path *path, unsigned int level) +void xdebug_path_info_add_path_for_level(xdebug_path_info *path_info, xdebug_path *path, unsigned int level TSRMLS_DC) { int i = 0, orig_size; @@ -155,7 +155,7 @@ void xdebug_path_info_add_path_for_level(xdebug_path_info *path_info, xdebug_pat path_info->paths[level] = path; } -xdebug_path *xdebug_path_info_get_path_for_level(xdebug_path_info *path_info, unsigned int level) +xdebug_path *xdebug_path_info_get_path_for_level(xdebug_path_info *path_info, unsigned int level TSRMLS_DC) { return path_info->paths[level]; } @@ -298,7 +298,7 @@ void xdebug_branch_info_dump(zend_op_array *opa, xdebug_branch_info *branch_info for (i = 0; i < branch_info->path_info.paths_count; i++) { printf("path #%d: ", i + 1); - xdebug_path_info_dump(branch_info->path_info.paths[i]); + xdebug_path_info_dump(branch_info->path_info.paths[i] TSRMLS_CC); } } diff --git a/xdebug_branch_info.h b/xdebug_branch_info.h index f1e8d77d8..8d794d670 100644 --- a/xdebug_branch_info.h +++ b/xdebug_branch_info.h @@ -74,8 +74,8 @@ void xdebug_path_add(xdebug_path *path, unsigned int nr); xdebug_path *xdebug_path_new(xdebug_path *old_path); void xdebug_path_info_dump(xdebug_path *path TSRMLS_DC); void xdebug_path_free(xdebug_path *path); -void xdebug_path_info_add_path_for_level(xdebug_path_info *path_info, xdebug_path *path, unsigned int level); -xdebug_path *xdebug_path_info_get_path_for_level(xdebug_path_info *path_info, unsigned int level); +void xdebug_path_info_add_path_for_level(xdebug_path_info *path_info, xdebug_path *path, unsigned int level TSRMLS_DC); +xdebug_path *xdebug_path_info_get_path_for_level(xdebug_path_info *path_info, unsigned int level TSRMLS_DC); void xdebug_create_key_for_path(xdebug_path *path, xdebug_str *str); void xdebug_branch_info_mark_reached(char *filename, char *function_name, zend_op_array *op_array, long opcode_nr TSRMLS_DC); diff --git a/xdebug_code_coverage.c b/xdebug_code_coverage.c index 62f000e0d..d07a3c1d6 100644 --- a/xdebug_code_coverage.c +++ b/xdebug_code_coverage.c @@ -82,7 +82,7 @@ void xdebug_coverage_function_dtor(void *data) xdfree(function); } -void xdebug_print_opcode_info(char type, zend_execute_data *execute_data, zend_op *cur_opcode) +void xdebug_print_opcode_info(char type, zend_execute_data *execute_data, zend_op *cur_opcode TSRMLS_DC) { zend_op_array *op_array = execute_data->op_array; char *file = (char *) op_array->filename; @@ -109,7 +109,7 @@ int xdebug_check_branch_entry_handler(ZEND_OPCODE_HANDLER_ARGS) zend_op *cur_opcode; cur_opcode = *EG(opline_ptr); - xdebug_print_opcode_info('G', execute_data, cur_opcode); + xdebug_print_opcode_info('G', execute_data, cur_opcode TSRMLS_CC); } return ZEND_USER_OPCODE_DISPATCH; } @@ -135,7 +135,7 @@ int xdebug_common_override_handler(ZEND_OPCODE_HANDLER_ARGS) file = (char *)op_array->filename; - xdebug_print_opcode_info('C', execute_data, cur_opcode); + xdebug_print_opcode_info('C', execute_data, cur_opcode TSRMLS_CC); xdebug_count_line(file, lineno, 0, 0 TSRMLS_CC); } return ZEND_USER_OPCODE_DISPATCH; @@ -301,7 +301,7 @@ static int xdebug_common_assign_dim_handler(char *op, int do_cc, ZEND_OPCODE_HAN lineno = cur_opcode->lineno; if (XG(do_code_coverage)) { - xdebug_print_opcode_info('=', execute_data, cur_opcode); + xdebug_print_opcode_info('=', execute_data, cur_opcode TSRMLS_CC); if (do_cc) { xdebug_count_line(file, lineno, 0, 0 TSRMLS_CC); @@ -792,7 +792,7 @@ void xdebug_code_coverage_start_of_function(zend_op_array *op_array TSRMLS_DC) xdebug_path *path = xdebug_path_new(NULL); xdebug_prefill_code_coverage(op_array TSRMLS_CC); - xdebug_path_info_add_path_for_level(&(XG(paths_stack)), path, XG(level)); + xdebug_path_info_add_path_for_level(&(XG(paths_stack)), path, XG(level) TSRMLS_CC); if (XG(branches).size == 0 || XG(level) > XG(branches).size) { XG(branches).size += 32; @@ -805,7 +805,7 @@ void xdebug_code_coverage_start_of_function(zend_op_array *op_array TSRMLS_DC) void xdebug_code_coverage_end_of_function(zend_op_array *op_array TSRMLS_DC) { xdebug_str str = { 0, 0, NULL }; - xdebug_path *path = xdebug_path_info_get_path_for_level(&(XG(paths_stack)), XG(level)); + xdebug_path *path = xdebug_path_info_get_path_for_level(&(XG(paths_stack)), XG(level) TSRMLS_CC); char *file = (char *) op_array->filename; xdebug_func func_info; char *function_name; @@ -986,13 +986,14 @@ static void add_cc_function(void *ret, xdebug_hash_element *e) xdebug_coverage_function *function = (xdebug_coverage_function*) e->ptr; zval *retval = (zval*) ret; zval *function_info; + TSRMLS_FETCH(); MAKE_STD_ZVAL(function_info); array_init(function_info); if (function->branch_info) { - add_branches(function_info, function->branch_info); - add_paths(function_info, function->branch_info); + add_branches(function_info, function->branch_info TSRMLS_CC); + add_paths(function_info, function->branch_info TSRMLS_CC); } add_assoc_zval_ex(retval, function->name, strlen(function->name) + 1, function_info); diff --git a/xdebug_code_coverage.h b/xdebug_code_coverage.h index 2fe387da4..d8aaf5cbd 100644 --- a/xdebug_code_coverage.h +++ b/xdebug_code_coverage.h @@ -56,7 +56,7 @@ void xdebug_coverage_file_dtor(void *data); xdebug_coverage_function *xdebug_coverage_function_ctor(char *function_name); void xdebug_coverage_function_dtor(void *data); -void xdebug_print_opcode_info(char type, zend_execute_data *execute_data, zend_op *cur_opcode); +void xdebug_print_opcode_info(char type, zend_execute_data *execute_data, zend_op *cur_opcode TSRMLS_DC); void xdebug_code_coverage_start_of_function(zend_op_array *op_array TSRMLS_DC); void xdebug_code_coverage_end_of_function(zend_op_array *op_array TSRMLS_DC); diff --git a/xdebug_stack.c b/xdebug_stack.c index 0d37f75f6..efbeb9f75 100644 --- a/xdebug_stack.c +++ b/xdebug_stack.c @@ -959,7 +959,7 @@ static void xdebug_build_fname(xdebug_func *tmp, zend_execute_data *edata TSRMLS fname = "whoops"; } - lineno = find_line_number_for_current_execute_point(edata TSRMLS_DC); + lineno = find_line_number_for_current_execute_point(edata TSRMLS_CC); tmp->function = xdebug_sprintf( "%s:{%s:%d}", diff --git a/xdebug_trace_html.c b/xdebug_trace_html.c index 12a1483a7..c3465c54c 100644 --- a/xdebug_trace_html.c +++ b/xdebug_trace_html.c @@ -26,7 +26,7 @@ void *xdebug_trace_html_init(char *fname, long options TSRMLS_DC) char *used_fname; tmp_html_context = xdmalloc(sizeof(xdebug_trace_html_context)); - tmp_html_context->trace_file = xdebug_trace_open_file(fname, options, (char**) &used_fname); + tmp_html_context->trace_file = xdebug_trace_open_file(fname, options, (char**) &used_fname TSRMLS_CC); tmp_html_context->trace_filename = used_fname; return tmp_html_context; @@ -129,6 +129,8 @@ xdebug_trace_handler_t xdebug_trace_handler_html = xdebug_trace_html_function_entry, NULL /* xdebug_trace_html_function_exit */, NULL /* xdebug_trace_html_function_return_value */, +#if PHP_VERSION_ID >= 50500 NULL /* xdebug_trace_html_generator_return_value */, - NULL, /* xdebug_trace_html_assignment */ +#endif + NULL /* xdebug_trace_html_assignment */ }; diff --git a/xdebug_tracing.c b/xdebug_tracing.c index a5109b6b2..0ab4efe15 100644 --- a/xdebug_tracing.c +++ b/xdebug_tracing.c @@ -136,7 +136,7 @@ PHP_FUNCTION(xdebug_start_trace) PHP_FUNCTION(xdebug_stop_trace) { if (XG(do_trace) == 1) { - RETVAL_STRING(XG(trace_handler)->get_filename(XG(trace_context)), 1); + RETVAL_STRING(XG(trace_handler)->get_filename(XG(trace_context) TSRMLS_CC), 1); xdebug_stop_trace(TSRMLS_C); } else { RETVAL_FALSE; @@ -146,8 +146,8 @@ PHP_FUNCTION(xdebug_stop_trace) PHP_FUNCTION(xdebug_get_tracefile_name) { - if (XG(trace_handler)->get_filename) { - RETURN_STRING(XG(trace_handler)->get_filename(XG(trace_context)), 1); + if (XG(do_trace) == 1 && XG(trace_handler) && XG(trace_handler)->get_filename) { + RETURN_STRING(XG(trace_handler)->get_filename(XG(trace_context) TSRMLS_CC), 1); } else { RETURN_FALSE; }