Skip to content

Commit 87df1a7

Browse files
committed
Introduce error notification callbacks that are run independant of zend_error_cb
1 parent 1a00d01 commit 87df1a7

File tree

6 files changed

+85
-26
lines changed

6 files changed

+85
-26
lines changed

Zend/zend.c

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

64+
zend_llist zend_error_notify_callbacks;
65+
6466
/* version information */
6567
static char *zend_version_info;
6668
static uint32_t zend_version_info_length;
@@ -815,6 +817,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
815817

816818
zend_startup_strtod();
817819
zend_startup_extensions_mechanism();
820+
zend_startup_error_notify_callbacks();
818821

819822
/* Set up utility functions and values */
820823
zend_error_cb = utility_functions->error_function;
@@ -846,6 +849,8 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */
846849
zend_compile_file = dtrace_compile_file;
847850
zend_execute_ex = dtrace_execute_ex;
848851
zend_execute_internal = dtrace_execute_internal;
852+
853+
zend_register_error_notify_callback(dtrace_error_notify_cb);
849854
} else {
850855
zend_compile_file = compile_file;
851856
zend_execute_ex = execute_ex;
@@ -1075,6 +1080,7 @@ void zend_shutdown(void) /* {{{ */
10751080
zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE);
10761081
free(GLOBAL_AUTO_GLOBALS_TABLE);
10771082

1083+
zend_shutdown_error_notify_callbacks();
10781084
zend_shutdown_extensions();
10791085
free(zend_version_info);
10801086

@@ -1311,11 +1317,7 @@ static ZEND_COLD void zend_error_impl(
13111317
}
13121318
}
13131319

1314-
#ifdef HAVE_DTRACE
1315-
if (DTRACE_ERROR_ENABLED()) {
1316-
DTRACE_ERROR(ZSTR_VAL(message), (char *)error_filename, error_lineno);
1317-
}
1318-
#endif /* HAVE_DTRACE */
1320+
zend_error_notify_all_callbacks(type, error_filename, error_lineno, message);
13191321

13201322
/* if we don't have a user defined error handler */
13211323
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
@@ -1771,3 +1773,29 @@ ZEND_API void zend_map_ptr_extend(size_t last)
17711773
CG(map_ptr_last) = last;
17721774
}
17731775
}
1776+
1777+
void zend_startup_error_notify_callbacks()
1778+
{
1779+
zend_llist_init(&zend_error_notify_callbacks, sizeof(zend_error_notify_cb), NULL, 1);
1780+
}
1781+
1782+
void zend_shutdown_error_notify_callbacks()
1783+
{
1784+
zend_llist_destroy(&zend_error_notify_callbacks);
1785+
}
1786+
1787+
void zend_register_error_notify_callback(zend_error_notify_cb cb)
1788+
{
1789+
zend_llist_add_element(&zend_error_notify_callbacks, &cb);
1790+
}
1791+
1792+
void zend_error_notify_all_callbacks(int type, const char *error_filename, uint32_t error_lineno, zend_string *message)
1793+
{
1794+
zend_llist_element *element;
1795+
zend_error_notify_cb callback;
1796+
1797+
for (element = zend_error_notify_callbacks.head; element; element = element->next) {
1798+
callback = *(zend_error_notify_cb *) (element->data);
1799+
callback(type, error_filename, error_lineno, message);
1800+
}
1801+
}

Zend/zend.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,16 @@ 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, uint32_t error_lineno, zend_string *message);
355+
356+
BEGIN_EXTERN_C()
357+
358+
void zend_register_error_notify_callback(zend_error_notify_cb callback);
359+
void zend_startup_error_notify_callbacks();
360+
void zend_shutdown_error_notify_callbacks();
361+
void zend_error_notify_all_callbacks(int type, const char *error_filename, uint32_t error_lineno, zend_string *message);
362+
END_EXTERN_C()
363+
354364
#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
355365
#define DEBUG_BACKTRACE_IGNORE_ARGS (1<<1)
356366

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, 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, uint32_t error_lineno, zend_string *message);
41+
4042
#endif /* HAVE_DTRACE */
4143

4244
#ifdef __cplusplus

Zend/zend_exceptions.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ static void zend_error_va(int type, const char *file, uint32_t lineno, const cha
893893
va_list args;
894894
va_start(args, format);
895895
zend_string *message = zend_vstrpprintf(0, format, args);
896+
zend_error_notify_all_callbacks(type, file, lineno, message);
896897
zend_error_cb(type, file, lineno, message);
897898
zend_string_release(message);
898899
va_end(args);
@@ -913,10 +914,10 @@ ZEND_API ZEND_COLD int zend_exception_error(zend_object *ex, int severity) /* {{
913914
zend_string *message = zval_get_string(GET_PROPERTY(&exception, ZEND_STR_MESSAGE));
914915
zend_string *file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE));
915916
zend_long line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE));
917+
int type = (ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL;
916918

917-
zend_error_cb(
918-
(ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL,
919-
ZSTR_VAL(file), line, message);
919+
zend_error_notify_all_callbacks(type, ZSTR_VAL(file), line, message);
920+
zend_error_cb(type, ZSTR_VAL(file), line, message);
920921

921922
zend_string_release_ex(file, 0);
922923
zend_string_release_ex(message, 0);

main/main.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,31 @@ static void clear_last_error() {
11751175
}
11761176
}
11771177

1178+
#if ZEND_DEBUG
1179+
/* {{{ report_zend_debug_error_notify_cb */
1180+
static void report_zend_debug_error_notify_cb(int type, const char *error_filename, uint32_t error_lineno, zend_string *message)
1181+
{
1182+
if (PG(report_zend_debug)) {
1183+
zend_bool trigger_break;
1184+
1185+
switch (type) {
1186+
case E_ERROR:
1187+
case E_CORE_ERROR:
1188+
case E_COMPILE_ERROR:
1189+
case E_USER_ERROR:
1190+
trigger_break=1;
1191+
break;
1192+
default:
1193+
trigger_break=0;
1194+
break;
1195+
}
1196+
1197+
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s", error_filename, error_lineno, ZSTR_VAL(message));
1198+
}
1199+
}
1200+
/* }}} */
1201+
#endif
1202+
11781203
/* {{{ php_error_cb
11791204
extended error handling function */
11801205
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
13301355
}
13311356
}
13321357
}
1333-
#if ZEND_DEBUG
1334-
if (PG(report_zend_debug)) {
1335-
zend_bool trigger_break;
1336-
1337-
switch (type) {
1338-
case E_ERROR:
1339-
case E_CORE_ERROR:
1340-
case E_COMPILE_ERROR:
1341-
case E_USER_ERROR:
1342-
trigger_break=1;
1343-
break;
1344-
default:
1345-
trigger_break=0;
1346-
break;
1347-
}
1348-
zend_output_debug_string(trigger_break, "%s(%" PRIu32 ") : %s - %s", error_filename, error_lineno, error_type_str, ZSTR_VAL(message));
1349-
}
1350-
#endif
13511358
}
13521359

13531360
/* Bail out if we can't recover */
@@ -2083,6 +2090,10 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
20832090
zend_startup(&zuf);
20842091
zend_update_current_locale();
20852092

2093+
#if ZEND_DEBUG
2094+
zend_register_error_notify_callback(report_zend_debug_error_notify_cb);
2095+
#endif
2096+
20862097
#if HAVE_TZSET
20872098
tzset();
20882099
#endif

0 commit comments

Comments
 (0)