function_stack_entry *xdebug_get_stack_frame(int nr TSRMLS_DC) { xdebug_llist_element *le; if (!XG(stack)) { return NULL; } if (!(le = XDEBUG_LLIST_TAIL(XG(stack)))) { return NULL; } if (nr < 0) { return NULL; } while (nr) { nr--; le = XDEBUG_LLIST_PREV(le); if (!le) { return NULL; } } return XDEBUG_LLIST_VALP(le); }
void xdebug_log_stack(const char *error_type_str, char *buffer, const char *error_filename, const int error_lineno TSRMLS_DC) { xdebug_llist_element *le; function_stack_entry *i; char *tmp_log_message; tmp_log_message = xdebug_sprintf( "PHP %s: %s in %s on line %d", error_type_str, buffer, error_filename, error_lineno); php_log_err(tmp_log_message TSRMLS_CC); xdfree(tmp_log_message); if (XG(stack) && XG(stack)->size) { php_log_err("PHP Stack trace:" TSRMLS_CC); for (le = XDEBUG_LLIST_HEAD(XG(stack)); le != NULL; le = XDEBUG_LLIST_NEXT(le)) { int c = 0; /* Comma flag */ unsigned int j = 0; /* Counter */ char *tmp_name; xdebug_str log_buffer = {0, 0, NULL}; i = XDEBUG_LLIST_VALP(le); tmp_name = xdebug_show_fname(i->function, 0, 0 TSRMLS_CC); xdebug_str_add(&log_buffer, xdebug_sprintf("PHP %3d. %s(", i->level, tmp_name), 1); xdfree(tmp_name); /* Printing vars */ for (j = 0; j < i->varc; j++) { char *tmp_varname, *tmp_value; if (c) { xdebug_str_addl(&log_buffer, ", ", 2, 0); } else { c = 1; } tmp_varname = i->var[j].name ? xdebug_sprintf("$%s = ", i->var[j].name) : xdstrdup(""); xdebug_str_add(&log_buffer, tmp_varname, 0); xdfree(tmp_varname); if (i->var[j].addr) { tmp_value = xdebug_get_zval_value(i->var[j].addr, 0, NULL); xdebug_str_add(&log_buffer, tmp_value, 0); xdfree(tmp_value); } else { xdebug_str_addl(&log_buffer, "*uninitialized*", 15, 0); } } xdebug_str_add(&log_buffer, xdebug_sprintf(") %s:%d", i->filename, i->lineno), 1); php_log_err(log_buffer.d TSRMLS_CC); xdebug_str_free(&log_buffer); } } }
xdebug_hash* xdebug_used_var_hash_from_llist(xdebug_llist *list) { xdebug_hash *tmp; xdebug_llist_element *le; char *var_name; tmp = xdebug_hash_alloc(32, xdebug_used_var_hash_from_llist_dtor); for (le = XDEBUG_LLIST_HEAD(list); le != NULL; le = XDEBUG_LLIST_NEXT(le)) { var_name = (char*) XDEBUG_LLIST_VALP(le); xdebug_hash_add(tmp, var_name, strlen(var_name), var_name); } return tmp; }
function_stack_entry *xdebug_get_stack_tail(TSRMLS_D) { xdebug_llist_element *le; if (XG(stack)) { if ((le = XDEBUG_LLIST_TAIL(XG(stack)))) { return XDEBUG_LLIST_VALP(le); } else { return NULL; } } else { return NULL; } }
void xdebug_append_printable_stack(xdebug_str *str, int html TSRMLS_DC) { xdebug_llist_element *le; function_stack_entry *i; int len; char **formats = select_formats(html TSRMLS_CC); if (XG(stack) && XG(stack)->size) { i = XDEBUG_LLIST_VALP(XDEBUG_LLIST_HEAD(XG(stack))); xdebug_str_add(str, formats[2], 0); for (le = XDEBUG_LLIST_HEAD(XG(stack)); le != NULL; le = XDEBUG_LLIST_NEXT(le)) { int c = 0; /* Comma flag */ int j = 0; /* Counter */ char *tmp_name; i = XDEBUG_LLIST_VALP(le); tmp_name = xdebug_show_fname(i->function, html, 0 TSRMLS_CC); if (html) { #if HAVE_PHP_MEMORY_USAGE xdebug_str_add(str, xdebug_sprintf(formats[3], i->level, i->time - XG(start_time), i->memory, tmp_name), 1); #else xdebug_str_add(str, xdebug_sprintf(formats[3], i->level, i->time - XG(start_time), tmp_name), 1); #endif } else { #if HAVE_PHP_MEMORY_USAGE xdebug_str_add(str, xdebug_sprintf(formats[3], i->time - XG(start_time), i->memory, i->level, tmp_name), 1); #else xdebug_str_add(str, xdebug_sprintf(formats[3], i->time - XG(start_time), i->level, tmp_name), 1); #endif } xdfree(tmp_name); /* Printing vars */ for (j = 0; j < i->varc; j++) { char *tmp_value, *tmp_fancy_value, *tmp_fancy_synop_value; int newlen; if (c) { xdebug_str_addl(str, ", ", 2, 0); } else { c = 1; } if (i->var[j].name && XG(collect_params) >= 4) { if (html) { xdebug_str_add(str, xdebug_sprintf("<span>$%s = </span>", i->var[j].name), 1); } else { xdebug_str_add(str, xdebug_sprintf("$%s = ", i->var[j].name), 1); } } if (i->var[j].addr) { if (html) { tmp_value = xdebug_get_zval_value(i->var[j].addr, 0, NULL); tmp_fancy_value = xdebug_xmlize(tmp_value, strlen(tmp_value), &newlen); tmp_fancy_synop_value = xdebug_get_zval_synopsis_fancy("", i->var[j].addr, &len, 0, NULL TSRMLS_CC); switch (XG(collect_params)) { case 1: // synopsis xdebug_str_add(str, xdebug_sprintf("<span>%s</span>", tmp_fancy_synop_value), 1); break; case 2: // synopsis + full in tooltip xdebug_str_add(str, xdebug_sprintf("<span title='%s'>%s</span>", tmp_fancy_value, tmp_fancy_synop_value), 1); break; case 3: // full default: xdebug_str_add(str, xdebug_sprintf("<span>%s</span>", tmp_fancy_value), 1); break; } xdfree(tmp_value); efree(tmp_fancy_value); xdfree(tmp_fancy_synop_value); } else { switch (XG(collect_params)) { case 1: // synopsis case 2: tmp_value = xdebug_get_zval_synopsis(i->var[j].addr, 0, NULL); break; case 3: default: tmp_value = xdebug_get_zval_value(i->var[j].addr, 0, NULL); break; } if (tmp_value) { xdebug_str_add(str, xdebug_sprintf("%s", tmp_value), 1); xdfree(tmp_value); } else { xdebug_str_addl(str, "???", 3, 0); } } } else { xdebug_str_addl(str, "???", 3, 0); } } if (i->include_filename) { xdebug_str_add(str, xdebug_sprintf(formats[4], i->include_filename), 1); } if (html) { if (strlen(XG(file_link_format)) > 0) { char *just_filename = strrchr(i->filename, DEFAULT_SLASH); char *file_link; create_file_link(&file_link, i->filename, i->lineno TSRMLS_CC); xdebug_str_add(str, xdebug_sprintf(formats[10], i->filename, file_link, just_filename, i->lineno), 1); xdfree(file_link); } else { char *just_filename = strrchr(i->filename, DEFAULT_SLASH); xdebug_str_add(str, xdebug_sprintf(formats[5], i->filename, just_filename, i->lineno), 1); } } else { xdebug_str_add(str, xdebug_sprintf(formats[5], i->filename, i->lineno), 1); } } if (XG(dump_globals) && !(XG(dump_once) && XG(dumped))) { char *tmp = xdebug_get_printable_superglobals(html TSRMLS_CC); if (tmp) { xdebug_str_add(str, tmp, 1); } XG(dumped) = 1; } if (XG(show_local_vars) && XG(stack) && XDEBUG_LLIST_TAIL(XG(stack))) { int scope_nr = XG(stack)->size; i = XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))); if (i->user_defined == XDEBUG_INTERNAL && XDEBUG_LLIST_PREV(XDEBUG_LLIST_TAIL(XG(stack))) && XDEBUG_LLIST_VALP(XDEBUG_LLIST_PREV(XDEBUG_LLIST_TAIL(XG(stack))))) { i = XDEBUG_LLIST_VALP(XDEBUG_LLIST_PREV(XDEBUG_LLIST_TAIL(XG(stack)))); scope_nr--; } if (i->used_vars && i->used_vars->size) { xdebug_hash *tmp_hash; xdebug_str_add(str, xdebug_sprintf(formats[6], scope_nr), 1); tmp_hash = xdebug_used_var_hash_from_llist(i->used_vars); xdebug_hash_apply_with_argument(tmp_hash, (void*) &html, dump_used_var_with_contents, (void *) str); xdebug_hash_destroy(tmp_hash); } } } }