Skip to content

Commit 28b1529

Browse files
committed
Introduce error notification callbacks that are run independant of zend_error_cb
1 parent e2f1586 commit 28b1529

File tree

5 files changed

+110
-26
lines changed

5 files changed

+110
-26
lines changed

Zend/zend.c

Lines changed: 48 additions & 8 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;
@@ -816,6 +818,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
816818

817819
zend_startup_strtod();
818820
zend_startup_extensions_mechanism();
821+
zend_startup_error_notify_callbacks();
819822

820823
/* Set up utility functions and values */
821824
zend_error_cb = utility_functions->error_function;
@@ -847,6 +850,8 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
847850
zend_compile_file = dtrace_compile_file;
848851
zend_execute_ex = dtrace_execute_ex;
849852
zend_execute_internal = dtrace_execute_internal;
853+
854+
zend_register_error_notify_callback(dtrace_error_notify_cb);
850855
} else {
851856
zend_compile_file = compile_file;
852857
zend_execute_ex = execute_ex;
@@ -1076,6 +1081,7 @@ void zend_shutdown(void) /* {{{ */
10761081
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
10771082
free(GLOBAL_AUTO_GLOBALS_TABLE);
10781083

1084+
zend_shutdown_error_notify_callbacks();
10791085
zend_shutdown_extensions();
10801086
free(zend_version_info);
10811087

@@ -1314,14 +1320,7 @@ static ZEND_COLD void zend_error_va_list(
13141320
}
13151321
}
13161322

1317-
#ifdef HAVE_DTRACE
1318-
if (DTRACE_ERROR_ENABLED()) {
1319-
char *dtrace_error_buffer;
1320-
zend_vspprintf(&dtrace_error_buffer, 0, format, args);
1321-
DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
1322-
efree(dtrace_error_buffer);
1323-
}
1324-
#endif /* HAVE_DTRACE */
1323+
zend_error_notify_all_callbacks(type, error_filename, error_lineno, format, args);
13251324

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

Zend/zend.h

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

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

Zend/zend_dtrace.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ 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, const char *format, va_list args)
113+
{
114+
if (DTRACE_ERROR_ENABLED()) {
115+
char *dtrace_error_buffer;
116+
zend_vspprintf(&dtrace_error_buffer, 0, format, args);
117+
DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
118+
efree(dtrace_error_buffer);
119+
}
120+
}
121+
112122
/* }}} */
113123

114124
#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, const char *format, va_list args);
41+
4042
#endif /* HAVE_DTRACE */
4143

4244
#ifdef __cplusplus

main/main.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,36 @@ PHPAPI void php_html_puts(const char *str, size_t size)
11881188
}
11891189
/* }}} */
11901190

1191+
#if ZEND_DEBUG
1192+
/* {{{ report_zend_debug_error_notify_cb */
1193+
void report_zend_debug_error_notify_cb(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args)
1194+
{
1195+
if (PG(report_zend_debug)) {
1196+
zend_bool trigger_break;
1197+
char *buffer;
1198+
1199+
vspprintf(&buffer, PG(log_errors_max_len), format, args);
1200+
1201+
switch (type) {
1202+
case E_ERROR:
1203+
case E_CORE_ERROR:
1204+
case E_COMPILE_ERROR:
1205+
case E_USER_ERROR:
1206+
trigger_break=1;
1207+
break;
1208+
default:
1209+
trigger_break=0;
1210+
break;
1211+
}
1212+
1213+
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s", error_filename, error_lineno, buffer);
1214+
1215+
efree(buffer);
1216+
}
1217+
}
1218+
/* }}} */
1219+
#endif
1220+
11911221
/* {{{ php_error_cb
11921222
extended error handling function */
11931223
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)
@@ -1356,24 +1386,6 @@ static ZEND_COLD void php_error_cb(int orig_type, const char *error_filename, co
13561386
}
13571387
}
13581388
}
1359-
#if ZEND_DEBUG
1360-
if (PG(report_zend_debug)) {
1361-
zend_bool trigger_break;
1362-
1363-
switch (type) {
1364-
case E_ERROR:
1365-
case E_CORE_ERROR:
1366-
case E_COMPILE_ERROR:
1367-
case E_USER_ERROR:
1368-
trigger_break=1;
1369-
break;
1370-
default:
1371-
trigger_break=0;
1372-
break;
1373-
}
1374-
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s - %s", error_filename, error_lineno, error_type_str, buffer);
1375-
}
1376-
#endif
13771389
}
13781390

13791391
/* Bail out if we can't recover */
@@ -2136,6 +2148,10 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
21362148
setlocale(LC_CTYPE, "");
21372149
zend_update_current_locale();
21382150

2151+
#if ZEND_DEBUG
2152+
zend_register_error_notify_callback(report_zend_debug_error_notify_cb);
2153+
#endif
2154+
21392155
#if HAVE_TZSET
21402156
tzset();
21412157
#endif

0 commit comments

Comments
 (0)