1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Introduce error notification callbacks that are run independant of zend_error_cb

This commit is contained in:
Benjamin Eberlei
2020-04-27 08:20:56 +02:00
parent 857166c351
commit 6c8b94eb42
6 changed files with 85 additions and 26 deletions

View File

@@ -61,6 +61,8 @@ ZEND_TSRMLS_CACHE_DEFINE()
ZEND_API zend_utility_values zend_uv;
ZEND_API zend_bool zend_dtrace_enabled;
zend_llist zend_error_notify_callbacks;
/* version information */
static char *zend_version_info;
static uint32_t zend_version_info_length;
@@ -815,6 +817,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
zend_startup_strtod();
zend_startup_extensions_mechanism();
zend_startup_error_notify_callbacks();
/* Set up utility functions and values */
zend_error_cb = utility_functions->error_function;
@@ -846,6 +849,8 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
zend_compile_file = dtrace_compile_file;
zend_execute_ex = dtrace_execute_ex;
zend_execute_internal = dtrace_execute_internal;
zend_register_error_notify_callback(dtrace_error_notify_cb);
} else {
zend_compile_file = compile_file;
zend_execute_ex = execute_ex;
@@ -1075,6 +1080,7 @@ void zend_shutdown(void) /* {{{ */
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
free(GLOBAL_AUTO_GLOBALS_TABLE);
zend_shutdown_error_notify_callbacks();
zend_shutdown_extensions();
free(zend_version_info);
@@ -1311,11 +1317,7 @@ static ZEND_COLD void zend_error_impl(
}
}
#ifdef HAVE_DTRACE
if (DTRACE_ERROR_ENABLED()) {
DTRACE_ERROR(ZSTR_VAL(message), (char *)error_filename, error_lineno);
}
#endif /* HAVE_DTRACE */
zend_error_notify_all_callbacks(type, error_filename, error_lineno, message);
/* if we don't have a user defined error handler */
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
@@ -1771,3 +1773,29 @@ ZEND_API void zend_map_ptr_extend(size_t last)
CG(map_ptr_last) = last;
}
}
void zend_startup_error_notify_callbacks()
{
zend_llist_init(&zend_error_notify_callbacks, sizeof(zend_error_notify_cb), NULL, 1);
}
void zend_shutdown_error_notify_callbacks()
{
zend_llist_destroy(&zend_error_notify_callbacks);
}
void zend_register_error_notify_callback(zend_error_notify_cb cb)
{
zend_llist_add_element(&zend_error_notify_callbacks, &cb);
}
void zend_error_notify_all_callbacks(int type, const char *error_filename, uint32_t error_lineno, zend_string *message)
{
zend_llist_element *element;
zend_error_notify_cb callback;
for (element = zend_error_notify_callbacks.head; element; element = element->next) {
callback = *(zend_error_notify_cb *) (element->data);
callback(type, error_filename, error_lineno, message);
}
}

View File

@@ -351,6 +351,16 @@ ZEND_API void zend_save_error_handling(zend_error_handling *current);
ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current);
ZEND_API void zend_restore_error_handling(zend_error_handling *saved);
typedef void (*zend_error_notify_cb)(int type, const char *error_filename, uint32_t error_lineno, zend_string *message);
BEGIN_EXTERN_C()
void zend_register_error_notify_callback(zend_error_notify_cb callback);
void zend_startup_error_notify_callbacks();
void zend_shutdown_error_notify_callbacks();
void zend_error_notify_all_callbacks(int type, const char *error_filename, uint32_t error_lineno, zend_string *message);
END_EXTERN_C()
#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
#define DEBUG_BACKTRACE_IGNORE_ARGS (1<<1)

View File

@@ -109,6 +109,13 @@ ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *ret
}
}
void dtrace_error_notify_cb(int type, const char *error_filename, uint32_t error_lineno, zend_string *message)
{
if (DTRACE_ERROR_ENABLED()) {
DTRACE_ERROR(ZSTR_VAL(message), (char *)error_filename, error_lineno);
}
}
/* }}} */
#endif /* HAVE_DTRACE */

View File

@@ -37,6 +37,8 @@ ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data);
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value);
#include <zend_dtrace_gen.h>
void dtrace_error_notify_cb(int type, const char *error_filename, uint32_t error_lineno, zend_string *message);
#endif /* HAVE_DTRACE */
#ifdef __cplusplus

View File

@@ -893,6 +893,7 @@ static void zend_error_va(int type, const char *file, uint32_t lineno, const cha
va_list args;
va_start(args, format);
zend_string *message = zend_vstrpprintf(0, format, args);
zend_error_notify_all_callbacks(type, file, lineno, message);
zend_error_cb(type, file, lineno, message);
zend_string_release(message);
va_end(args);
@@ -913,10 +914,10 @@ ZEND_API ZEND_COLD int zend_exception_error(zend_object *ex, int severity) /* {{
zend_string *message = zval_get_string(GET_PROPERTY(&exception, ZEND_STR_MESSAGE));
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));
int type = (ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL;
zend_error_cb(
(ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL,
ZSTR_VAL(file), line, message);
zend_error_notify_all_callbacks(type, ZSTR_VAL(file), line, message);
zend_error_cb(type, ZSTR_VAL(file), line, message);
zend_string_release_ex(file, 0);
zend_string_release_ex(message, 0);

View File

@@ -1175,6 +1175,31 @@ static void clear_last_error() {
}
}
#if ZEND_DEBUG
/* {{{ report_zend_debug_error_notify_cb */
static void report_zend_debug_error_notify_cb(int type, const char *error_filename, uint32_t error_lineno, zend_string *message)
{
if (PG(report_zend_debug)) {
zend_bool trigger_break;
switch (type) {
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
trigger_break=1;
break;
default:
trigger_break=0;
break;
}
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s", error_filename, error_lineno, ZSTR_VAL(message));
}
}
/* }}} */
#endif
/* {{{ php_error_cb
extended error handling function */
static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, const uint32_t error_lineno, zend_string *message)
@@ -1330,24 +1355,6 @@ static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, co
}
}
}
#if ZEND_DEBUG
if (PG(report_zend_debug)) {
zend_bool trigger_break;
switch (type) {
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
trigger_break=1;
break;
default:
trigger_break=0;
break;
}
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s - %s", error_filename, error_lineno, error_type_str, ZSTR_VAL(message));
}
#endif
}
/* Bail out if we can't recover */
@@ -2083,6 +2090,10 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
zend_startup(&zuf);
zend_update_current_locale();
#if ZEND_DEBUG
zend_register_error_notify_callback(report_zend_debug_error_notify_cb);
#endif
#if HAVE_TZSET
tzset();
#endif