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);
        }
    }
}
예제 #2
0
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);
			}
		}
	}
}