diff --git a/Zend/zend.c b/Zend/zend.c index 080a75a3c419..2f1f1562f851 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -174,6 +174,7 @@ ZEND_INI_BEGIN() #ifdef ZEND_SIGNALS STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals) #endif + STD_ZEND_INI_BOOLEAN("zend.log_exception_trace", "0", ZEND_INI_ALL, OnUpdateBool, log_exception_trace, zend_compiler_globals, compiler_globals) ZEND_INI_END() ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */ diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index e53ea1f1c763..e0baff987484 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -664,10 +664,11 @@ ZEND_METHOD(exception, __toString) { zval trace, *exception; zend_class_entry *base_ce; - zend_string *str; + zend_string *str, *tmpstr; zend_fcall_info fci; zval rv, tmp; zend_string *fname; + size_t str_len; DEFAULT_0_PARAMS; @@ -704,17 +705,31 @@ ZEND_METHOD(exception, __toString) } if (ZSTR_LEN(message) > 0) { - str = zend_strpprintf(0, "%s: %s in %s:" ZEND_LONG_FMT - "\nStack trace:\n%s%s%s", - ZSTR_VAL(Z_OBJCE_P(exception)->name), ZSTR_VAL(message), ZSTR_VAL(file), line, - (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n", - ZSTR_LEN(prev_str) ? "\n\nNext " : "", ZSTR_VAL(prev_str)); + str = zend_strpprintf(0, "%s: %s in %s:" ZEND_LONG_FMT, + ZSTR_VAL(Z_OBJCE_P(exception)->name), ZSTR_VAL(message), ZSTR_VAL(file), line); } else { - str = zend_strpprintf(0, "%s in %s:" ZEND_LONG_FMT - "\nStack trace:\n%s%s%s", - ZSTR_VAL(Z_OBJCE_P(exception)->name), ZSTR_VAL(file), line, - (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n", - ZSTR_LEN(prev_str) ? "\n\nNext " : "", ZSTR_VAL(prev_str)); + str = zend_strpprintf(0, "%s in %s:" ZEND_LONG_FMT, + ZSTR_VAL(Z_OBJCE_P(exception)->name), ZSTR_VAL(file), line); + } + + if (CG(log_exception_trace)) { + /* Add the strack trace */ + str_len = ZSTR_LEN(str); + tmpstr = ZSTR_EMPTY_ALLOC(); + tmpstr = zend_strpprintf(0, "\nStack trace:\n%s", + (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n"); + str = zend_string_extend(str, str_len + ZSTR_LEN(tmpstr), 0); + memcpy(ZSTR_VAL(str) + str_len, ZSTR_VAL(tmpstr), ZSTR_LEN(tmpstr)); + zend_string_release_ex(tmpstr, 0); + } + + if(ZSTR_LEN(prev_str) > 0) { + str_len = ZSTR_LEN(str); + tmpstr = ZSTR_EMPTY_ALLOC(); + tmpstr = zend_strpprintf(0, "\n\nNext %s", ZSTR_VAL(prev_str)); + str = zend_string_extend(str, str_len + ZSTR_LEN(tmpstr), 0); + memcpy(ZSTR_VAL(str) + str_len, ZSTR_VAL(tmpstr), ZSTR_LEN(tmpstr)); + zend_string_release_ex(tmpstr, 0); } zend_string_release_ex(prev_str, 0); diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index d88fdabcf7f2..ce9dd475502e 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -127,6 +127,8 @@ struct _zend_compiler_globals { HashTable *delayed_variance_obligations; HashTable *delayed_autoloads; + + zend_bool log_exception_trace; }; diff --git a/php.ini-development b/php.ini-development index c78921980ea2..4e8308b9f815 100644 --- a/php.ini-development +++ b/php.ini-development @@ -354,6 +354,11 @@ zend.enable_gc = On ; Default: "" ;zend.script_encoding = +; Add stack traces to fatal errors and exceptions. This could potentially contain +; sensitive information and should not be enabled in a production environment. +; Default: Off +;zend.log_exception_trace = Off + ;;;;;;;;;;;;;;;;; ; Miscellaneous ; ;;;;;;;;;;;;;;;;; diff --git a/php.ini-production b/php.ini-production index e3f061e3fbae..befefc9a9829 100644 --- a/php.ini-production +++ b/php.ini-production @@ -359,6 +359,11 @@ zend.enable_gc = On ; Default: "" ;zend.script_encoding = +; Add stack traces to fatal errors and exceptions. This could potentially contain +; sensitive information and should not be enabled in a production environment. +; Default: Off +;zend.log_exception_trace = Off + ;;;;;;;;;;;;;;;;; ; Miscellaneous ; ;;;;;;;;;;;;;;;;;