Skip to content

Commit ccffa02

Browse files
committed
Introduce error notification callbacks that are run independant of zend_error_cb
1 parent 975acfe commit ccffa02

File tree

5 files changed

+99
-23
lines changed

5 files changed

+99
-23
lines changed

Zend/zend.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ ZEND_TSRMLS_CACHE_DEFINE()
6060
ZEND_API zend_utility_values zend_uv;
6161
ZEND_API zend_bool zend_dtrace_enabled;
6262

63+
zend_llist zend_error_notify_callbacks;
64+
6365
/* version information */
6466
static char *zend_version_info;
6567
static uint32_t zend_version_info_length;
@@ -808,6 +810,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
808810

809811
zend_startup_strtod();
810812
zend_startup_extensions_mechanism();
813+
zend_startup_error_notify_callbacks();
811814

812815
/* Set up utility functions and values */
813816
zend_error_cb = utility_functions->error_function;
@@ -839,6 +842,8 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
839842
zend_compile_file = dtrace_compile_file;
840843
zend_execute_ex = dtrace_execute_ex;
841844
zend_execute_internal = dtrace_execute_internal;
845+
846+
zend_register_error_notify_callback(dtrace_error_notify_cb);
842847
} else {
843848
zend_compile_file = compile_file;
844849
zend_execute_ex = execute_ex;
@@ -1068,6 +1073,7 @@ void zend_shutdown(void) /* {{{ */
10681073
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
10691074
free(GLOBAL_AUTO_GLOBALS_TABLE);
10701075

1076+
zend_shutdown_error_notify_callbacks();
10711077
zend_shutdown_extensions();
10721078
free(zend_version_info);
10731079

@@ -1304,11 +1310,7 @@ static ZEND_COLD void zend_error_impl(
13041310
}
13051311
}
13061312

1307-
#ifdef HAVE_DTRACE
1308-
if (DTRACE_ERROR_ENABLED()) {
1309-
DTRACE_ERROR(ZSTR_VAL(message), (char *)error_filename, error_lineno);
1310-
}
1311-
#endif /* HAVE_DTRACE */
1313+
zend_error_notify_all_callbacks(type, error_filename, error_lineno, message);
13121314

13131315
/* if we don't have a user defined error handler */
13141316
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
@@ -1765,3 +1767,41 @@ ZEND_API void zend_map_ptr_extend(size_t last)
17651767
CG(map_ptr_last) = last;
17661768
}
17671769
}
1770+
1771+
static void zend_error_notify_callback_dtor(zend_error_notify_callback *callback)
1772+
{
1773+
}
1774+
1775+
int zend_startup_error_notify_callbacks()
1776+
{
1777+
zend_llist_init(&zend_error_notify_callbacks, sizeof(zend_error_notify_callback), (void (*)(void *)) zend_error_notify_callback_dtor, 1);
1778+
1779+
return SUCCESS;
1780+
}
1781+
1782+
int zend_shutdown_error_notify_callbacks()
1783+
{
1784+
zend_llist_destroy(&zend_error_notify_callbacks);
1785+
1786+
return SUCCESS;
1787+
}
1788+
1789+
void zend_register_error_notify_callback(zend_error_notify_cb cb)
1790+
{
1791+
zend_error_notify_callback callback;
1792+
1793+
callback.notify_callback = cb;
1794+
1795+
zend_llist_add_element(&zend_error_notify_callbacks, &callback);
1796+
}
1797+
1798+
void zend_error_notify_all_callbacks(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message)
1799+
{
1800+
zend_llist_element *element;
1801+
zend_error_notify_callback *callback;
1802+
1803+
for (element = zend_error_notify_callbacks.head; element; element = element->next) {
1804+
callback = (zend_error_notify_callback*) element->data;
1805+
callback->notify_callback(type, error_filename, error_lineno, message);
1806+
}
1807+
}

Zend/zend.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,22 @@ ZEND_API void zend_save_error_handling(zend_error_handling *current);
351351
ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current);
352352
ZEND_API void zend_restore_error_handling(zend_error_handling *saved);
353353

354+
typedef void (*zend_error_notify_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
355+
356+
BEGIN_EXTERN_C()
357+
typedef struct {
358+
zend_error_notify_cb notify_callback;
359+
} zend_error_notify_callback;
360+
361+
void zend_register_error_notify_callback(zend_error_notify_cb callback);
362+
int zend_startup_error_notify_callbacks();
363+
int zend_shutdown_error_notify_callbacks();
364+
void zend_error_notify_all_callbacks(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
365+
#if ZEND_DEBUG
366+
void report_zend_debug_error_notify_cb(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
367+
#endif
368+
END_EXTERN_C()
369+
354370
#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
355371
#define DEBUG_BACKTRACE_IGNORE_ARGS (1<<1)
356372

Zend/zend_dtrace.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *ret
109109
}
110110
}
111111

112+
void dtrace_error_notify_cb(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message)
113+
{
114+
if (DTRACE_ERROR_ENABLED()) {
115+
DTRACE_ERROR(ZSTR_VAL(message), (char *)error_filename, error_lineno);
116+
}
117+
}
118+
112119
/* }}} */
113120

114121
#endif /* HAVE_DTRACE */

Zend/zend_dtrace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data);
3737
ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data, zval *return_value);
3838
#include <zend_dtrace_gen.h>
3939

40+
void dtrace_error_notify_cb(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
41+
4042
#endif /* HAVE_DTRACE */
4143

4244
#ifdef __cplusplus

main/main.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,31 @@ static void clear_last_error() {
11991199
}
12001200
}
12011201

1202+
#if ZEND_DEBUG
1203+
/* {{{ report_zend_debug_error_notify_cb */
1204+
void report_zend_debug_error_notify_cb(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message)
1205+
{
1206+
if (PG(report_zend_debug)) {
1207+
zend_bool trigger_break;
1208+
1209+
switch (type) {
1210+
case E_ERROR:
1211+
case E_CORE_ERROR:
1212+
case E_COMPILE_ERROR:
1213+
case E_USER_ERROR:
1214+
trigger_break=1;
1215+
break;
1216+
default:
1217+
trigger_break=0;
1218+
break;
1219+
}
1220+
1221+
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s", error_filename, error_lineno, ZSTR_VAL(message));
1222+
}
1223+
}
1224+
/* }}} */
1225+
#endif
1226+
12021227
/* {{{ php_error_cb
12031228
extended error handling function */
12041229
static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, const uint32_t error_lineno, zend_string *message)
@@ -1354,24 +1379,6 @@ static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, co
13541379
}
13551380
}
13561381
}
1357-
#if ZEND_DEBUG
1358-
if (PG(report_zend_debug)) {
1359-
zend_bool trigger_break;
1360-
1361-
switch (type) {
1362-
case E_ERROR:
1363-
case E_CORE_ERROR:
1364-
case E_COMPILE_ERROR:
1365-
case E_USER_ERROR:
1366-
trigger_break=1;
1367-
break;
1368-
default:
1369-
trigger_break=0;
1370-
break;
1371-
}
1372-
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s - %s", error_filename, error_lineno, error_type_str, ZSTR_VAL(message));
1373-
}
1374-
#endif
13751382
}
13761383

13771384
/* Bail out if we can't recover */
@@ -2121,6 +2128,10 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
21212128
zend_startup(&zuf);
21222129
zend_update_current_locale();
21232130

2131+
#if ZEND_DEBUG
2132+
zend_register_error_notify_callback(report_zend_debug_error_notify_cb);
2133+
#endif
2134+
21242135
#if HAVE_TZSET
21252136
tzset();
21262137
#endif

0 commit comments

Comments
 (0)