mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Use clean shutdown on uncaught exception
This commit is contained in:
parent
aab1445b4c
commit
db233501ff
7 changed files with 26 additions and 16 deletions
|
@ -112,6 +112,8 @@ PHP 8.0 UPGRADE NOTES
|
|||
. Unexpected characters in source files (such as null bytes outside of
|
||||
strings) will now result in a ParseError exception instead of a compile
|
||||
warning.
|
||||
. Uncaught exceptions now go through "clean shutdown", which means that
|
||||
destructors will be called after an uncaught exception.
|
||||
|
||||
- COM:
|
||||
. Removed the ability to import case-insensitive constants from type
|
||||
|
|
|
@ -15,3 +15,4 @@ Fatal error: Uncaught Error: Call to undefined function bar() in %sbug36268.php:
|
|||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %sbug36268.php on line 8
|
||||
Ha!
|
||||
|
|
20
Zend/zend.c
20
Zend/zend.c
|
@ -1246,7 +1246,7 @@ ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
|
|||
} while (0)
|
||||
|
||||
static ZEND_COLD void zend_error_va_list(
|
||||
int type, const char *error_filename, uint32_t error_lineno,
|
||||
int orig_type, const char *error_filename, uint32_t error_lineno,
|
||||
const char *format, va_list args)
|
||||
{
|
||||
va_list usr_copy;
|
||||
|
@ -1258,6 +1258,7 @@ static ZEND_COLD void zend_error_va_list(
|
|||
zend_stack loop_var_stack;
|
||||
zend_stack delayed_oplines_stack;
|
||||
zend_class_entry *orig_fake_scope;
|
||||
int type = orig_type & E_ALL;
|
||||
|
||||
/* Report about uncaught exception in case of fatal errors */
|
||||
if (EG(exception)) {
|
||||
|
@ -1304,7 +1305,7 @@ static ZEND_COLD void zend_error_va_list(
|
|||
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|
||||
|| !(EG(user_error_handler_error_reporting) & type)
|
||||
|| EG(error_handling) != EH_NORMAL) {
|
||||
zend_error_cb(type, error_filename, error_lineno, format, args);
|
||||
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
|
||||
} else switch (type) {
|
||||
case E_ERROR:
|
||||
case E_PARSE:
|
||||
|
@ -1313,7 +1314,7 @@ static ZEND_COLD void zend_error_va_list(
|
|||
case E_COMPILE_ERROR:
|
||||
case E_COMPILE_WARNING:
|
||||
/* The error may not be safe to handle in user-space */
|
||||
zend_error_cb(type, error_filename, error_lineno, format, args);
|
||||
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
|
||||
break;
|
||||
default:
|
||||
/* Handle the error in user space */
|
||||
|
@ -1354,13 +1355,13 @@ static ZEND_COLD void zend_error_va_list(
|
|||
if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params) == SUCCESS) {
|
||||
if (Z_TYPE(retval) != IS_UNDEF) {
|
||||
if (Z_TYPE(retval) == IS_FALSE) {
|
||||
zend_error_cb(type, error_filename, error_lineno, format, args);
|
||||
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
|
||||
}
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
} else if (!EG(exception)) {
|
||||
/* The user error handler failed, use built-in error handler */
|
||||
zend_error_cb(type, error_filename, error_lineno, format, args);
|
||||
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
|
||||
}
|
||||
|
||||
EG(fake_scope) = orig_fake_scope;
|
||||
|
@ -1626,9 +1627,10 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
|
|||
int i;
|
||||
zend_file_handle *file_handle;
|
||||
zend_op_array *op_array;
|
||||
int ret = SUCCESS;
|
||||
|
||||
va_start(files, file_count);
|
||||
for (i = 0; i < file_count; i++) {
|
||||
for (i = 0; i < file_count && ret != FAILURE; i++) {
|
||||
file_handle = va_arg(files, zend_file_handle *);
|
||||
if (!file_handle) {
|
||||
continue;
|
||||
|
@ -1648,18 +1650,18 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
|
|||
}
|
||||
if (EG(exception)) {
|
||||
zend_exception_error(EG(exception), E_ERROR);
|
||||
ret = FAILURE;
|
||||
}
|
||||
}
|
||||
destroy_op_array(op_array);
|
||||
efree_size(op_array, sizeof(zend_op_array));
|
||||
} else if (type==ZEND_REQUIRE) {
|
||||
va_end(files);
|
||||
return FAILURE;
|
||||
ret = FAILURE;
|
||||
}
|
||||
}
|
||||
va_end(files);
|
||||
|
||||
return SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
#define E_DEPRECATED (1<<13L)
|
||||
#define E_USER_DEPRECATED (1<<14L)
|
||||
|
||||
/* Indicates that this usually fatal error should not result in a bailout */
|
||||
#define E_DONT_BAIL (1<<15L)
|
||||
|
||||
#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_RECOVERABLE_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_STRICT)
|
||||
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
|
||||
|
||||
|
|
|
@ -157,8 +157,9 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zval *exception) /* {{{ */
|
|||
if (exception && (Z_OBJCE_P(exception) == zend_ce_parse_error || Z_OBJCE_P(exception) == zend_ce_compile_error)) {
|
||||
return;
|
||||
}
|
||||
if(EG(exception)) {
|
||||
if (EG(exception)) {
|
||||
zend_exception_error(EG(exception), E_ERROR);
|
||||
zend_bailout();
|
||||
}
|
||||
zend_error_noreturn(E_CORE_ERROR, "Exception thrown without a stack frame");
|
||||
}
|
||||
|
@ -991,7 +992,8 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
|
|||
zend_string *file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE));
|
||||
zend_long line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE));
|
||||
|
||||
zend_error_helper(ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR,
|
||||
zend_error_helper(
|
||||
(ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL,
|
||||
ZSTR_VAL(file), line, "%s", ZSTR_VAL(message));
|
||||
|
||||
zend_string_release_ex(file, 0);
|
||||
|
@ -1034,7 +1036,8 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
|
|||
file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE));
|
||||
line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE));
|
||||
|
||||
zend_error_va(severity, (file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line,
|
||||
zend_error_va(severity | E_DONT_BAIL,
|
||||
(file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line,
|
||||
"Uncaught %s\n thrown", ZSTR_VAL(str));
|
||||
|
||||
zend_string_release_ex(str, 0);
|
||||
|
|
|
@ -1192,10 +1192,11 @@ PHPAPI void php_html_puts(const char *str, size_t size)
|
|||
|
||||
/* {{{ php_error_cb
|
||||
extended error handling function */
|
||||
static ZEND_COLD void php_error_cb(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args)
|
||||
static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args)
|
||||
{
|
||||
char *buffer;
|
||||
int buffer_len, display;
|
||||
int type = orig_type & E_ALL;
|
||||
|
||||
buffer_len = (int)vspprintf(&buffer, PG(log_errors_max_len), format, args);
|
||||
|
||||
|
@ -1403,7 +1404,7 @@ static ZEND_COLD void php_error_cb(int type, const char *error_filename, const u
|
|||
sapi_header_op(SAPI_HEADER_REPLACE, &ctr);
|
||||
}
|
||||
/* the parser would return 1 (failure), we can bail out nicely */
|
||||
if (type != E_PARSE) {
|
||||
if (!(orig_type & E_DONT_BAIL)) {
|
||||
/* restore memory limit */
|
||||
zend_set_memory_limit(PG(memory_limit));
|
||||
efree(buffer);
|
||||
|
|
|
@ -2202,8 +2202,6 @@ static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server
|
|||
decline = Z_TYPE(retval) == IS_FALSE;
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
} else {
|
||||
decline = 1;
|
||||
}
|
||||
} zend_end_try();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue