diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-26 15:46:09 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-26 15:47:00 +0100 |
commit | 0122f395c7dc5afb9feb3e2dcd11bb90e7433948 (patch) | |
tree | fad0964b53bcfb35d23b2da2dbd2ad79bd66d814 | |
parent | a9b01b60d89506b4f661b7108836d217158e83a2 (diff) | |
download | php-git-0122f395c7dc5afb9feb3e2dcd11bb90e7433948.tar.gz |
Add zend_error_at API that accepts a filename and lineno
Use this for the opcache preloading warnings, as an example usage.
-rw-r--r-- | Zend/zend.c | 166 | ||||
-rw-r--r-- | Zend/zend.h | 14 | ||||
-rw-r--r-- | ext/opcache/ZendAccelerator.c | 18 | ||||
-rw-r--r-- | ext/opcache/tests/preload_004.phpt | 2 | ||||
-rw-r--r-- | ext/opcache/tests/preload_009.phpt | 2 |
5 files changed, 101 insertions, 101 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index 2c2bd09081..721a097117 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1239,20 +1239,13 @@ ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */ } \ } while (0) -#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS) -ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) /* {{{ */ -#else -static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list args) -#endif +static ZEND_COLD void zend_error_va_list( + int type, const char *error_filename, uint32_t error_lineno, + const char *format, va_list args) { -#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS) - va_list args; -#endif va_list usr_copy; zval params[5]; zval retval; - const char *error_filename; - uint32_t error_lineno = 0; zval orig_user_error_handler; zend_bool in_compilation; zend_class_entry *saved_class_entry; @@ -1293,70 +1286,15 @@ static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list a } } - /* Obtain relevant filename and lineno */ - switch (type) { - case E_CORE_ERROR: - case E_CORE_WARNING: - error_filename = NULL; - error_lineno = 0; - break; - case E_PARSE: - case E_COMPILE_ERROR: - case E_COMPILE_WARNING: - case E_ERROR: - case E_NOTICE: - case E_STRICT: - case E_DEPRECATED: - case E_WARNING: - case E_USER_ERROR: - case E_USER_WARNING: - case E_USER_NOTICE: - case E_USER_DEPRECATED: - case E_RECOVERABLE_ERROR: - if (zend_is_compiling()) { - error_filename = ZSTR_VAL(zend_get_compiled_filename()); - error_lineno = zend_get_compiled_lineno(); - } else if (zend_is_executing()) { - error_filename = zend_get_executed_filename(); - if (error_filename[0] == '[') { /* [no active file] */ - error_filename = NULL; - error_lineno = 0; - } else { - error_lineno = zend_get_executed_lineno(); - } - } else { - error_filename = NULL; - error_lineno = 0; - } - break; - default: - error_filename = NULL; - error_lineno = 0; - break; - } - if (!error_filename) { - error_filename = "Unknown"; - } - #ifdef HAVE_DTRACE if (DTRACE_ERROR_ENABLED()) { char *dtrace_error_buffer; -#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS) - va_start(args, format); -#endif zend_vspprintf(&dtrace_error_buffer, 0, format, args); DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno); efree(dtrace_error_buffer); -#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS) - va_end(args); -#endif } #endif /* HAVE_DTRACE */ -#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS) - va_start(args, format); -#endif - /* if we don't have a user defined error handler */ if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF || !(EG(user_error_handler_error_reporting) & type) @@ -1450,10 +1388,6 @@ static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list a break; } -#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS) - va_end(args); -#endif - if (type == E_PARSE) { /* eval() errors do not affect exit_status */ if (!(EG(current_execute_data) && @@ -1467,30 +1401,92 @@ static ZEND_COLD void zend_error_va_list(int type, const char *format, va_list a } /* }}} */ -#ifdef HAVE_NORETURN -# ifdef HAVE_NORETURN_ALIAS -ZEND_COLD void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((alias("zend_error"),noreturn)); -# else -ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) /* {{{ */ -{ - va_list va; +static void get_filename_lineno(int type, const char **filename, uint32_t *lineno) { + /* Obtain relevant filename and lineno */ + switch (type) { + case E_CORE_ERROR: + case E_CORE_WARNING: + *filename = NULL; + *lineno = 0; + break; + case E_PARSE: + case E_COMPILE_ERROR: + case E_COMPILE_WARNING: + case E_ERROR: + case E_NOTICE: + case E_STRICT: + case E_DEPRECATED: + case E_WARNING: + case E_USER_ERROR: + case E_USER_WARNING: + case E_USER_NOTICE: + case E_USER_DEPRECATED: + case E_RECOVERABLE_ERROR: + if (zend_is_compiling()) { + *filename = ZSTR_VAL(zend_get_compiled_filename()); + *lineno = zend_get_compiled_lineno(); + } else if (zend_is_executing()) { + *filename = zend_get_executed_filename(); + if ((*filename)[0] == '[') { /* [no active file] */ + *filename = NULL; + *lineno = 0; + } else { + *lineno = zend_get_executed_lineno(); + } + } else { + *filename = NULL; + *lineno = 0; + } + break; + default: + *filename = NULL; + *lineno = 0; + break; + } + if (!*filename) { + *filename = "Unknown"; + } +} - va_start(va, format); - zend_error_va_list(type, format, va); - va_end(va); +ZEND_API ZEND_COLD void zend_error_at( + int type, const char *filename, uint32_t lineno, const char *format, ...) { + va_list args; + + if (!filename) { + uint32_t dummy_lineno; + get_filename_lineno(type, &filename, &dummy_lineno); + } + + va_start(args, format); + zend_error_va_list(type, filename, lineno, format, args); + va_end(args); +} + +ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) { + const char *filename; + uint32_t lineno; + va_list args; + + get_filename_lineno(type, &filename, &lineno); + va_start(args, format); + zend_error_va_list(type, filename, lineno, format, args); + va_end(args); } ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) { - va_list va; + const char *filename; + uint32_t lineno; + va_list args; - va_start(va, format); - zend_error_va_list(type, format, va); - va_end(va); + get_filename_lineno(type, &filename, &lineno); + va_start(args, format); + zend_error_va_list(type, filename, lineno, format, args); + va_end(args); + /* Should never reach this. */ + abort(); } /* }}} */ -# endif -#endif ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */ { diff --git a/Zend/zend.h b/Zend/zend.h index 73a56a0ccb..70c3d82c83 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -71,16 +71,6 @@ ZEND_TSRMLS_CACHE_EXTERN() -#ifdef HAVE_NORETURN -# ifdef ZEND_NORETURN_ALIAS -ZEND_COLD void zend_error_noreturn(int type, const char *format, ...) ZEND_NORETURN ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); -# else -ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); -# endif -#else -# define zend_error_noreturn zend_error -#endif - struct _zend_serialize_data; struct _zend_unserialize_data; @@ -303,6 +293,10 @@ extern ZEND_API int (*zend_post_startup_cb)(void); extern ZEND_API void (*zend_post_shutdown_cb)(void); ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); +ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); +/* If filename is NULL the default filename is used. */ +ZEND_API ZEND_COLD void zend_error_at(int type, const char *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5); + ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2); ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 7c71e1d5ef..0bdee2bfe0 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -3498,17 +3498,27 @@ static void preload_link(void) if (!(ce->ce_flags & ZEND_ACC_LINKED)) { zend_string *key = zend_string_tolower(ce->name); if (zend_hash_exists(EG(class_table), key)) { - zend_error(E_WARNING, "Can't preload already declared class %s at %s:%d", ZSTR_VAL(ce->name), ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start); + zend_error_at( + E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, + "Can't preload already declared class %s", ZSTR_VAL(ce->name)); } else { - zend_error(E_WARNING, "Can't preload unlinked class %s at %s:%d", ZSTR_VAL(ce->name), ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start); + zend_error_at( + E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, + "Can't preload unlinked class %s", ZSTR_VAL(ce->name)); } zend_string_release(key); } else if (!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { const char *kind, *name; get_unresolved_initializer(ce, &kind, &name); - zend_error(E_WARNING, "Can't preload class %s with unresolved initializer for %s%s at %s:%d", ZSTR_VAL(ce->name), kind, name, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start); + zend_error_at( + E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, + "Can't preload class %s with unresolved initializer for %s%s", + ZSTR_VAL(ce->name), kind, name); } else if (!(ce->ce_flags & ZEND_ACC_PROPERTY_TYPES_RESOLVED)) { - zend_error(E_WARNING, "Can't preload class %s with unresolved property types at %s:%d", ZSTR_VAL(ce->name), ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start); + zend_error_at( + E_WARNING, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, + "Can't preload class %s with unresolved property types", + ZSTR_VAL(ce->name)); } else { continue; } diff --git a/ext/opcache/tests/preload_004.phpt b/ext/opcache/tests/preload_004.phpt index 690d7f84fe..0441c78883 100644 --- a/ext/opcache/tests/preload_004.phpt +++ b/ext/opcache/tests/preload_004.phpt @@ -12,5 +12,5 @@ opcache.preload={PWD}/preload_undef_const.inc var_dump(class_exists('Foo')); ?> --EXPECTF-- -Warning: Can't preload class Foo with unresolved initializer for constant A at %s:%d in Unknown on line 0 +Warning: Can't preload class Foo with unresolved initializer for constant A in %spreload_undef_const.inc on line 2 bool(false) diff --git a/ext/opcache/tests/preload_009.phpt b/ext/opcache/tests/preload_009.phpt index 21c4766231..84f444768c 100644 --- a/ext/opcache/tests/preload_009.phpt +++ b/ext/opcache/tests/preload_009.phpt @@ -13,6 +13,6 @@ var_dump(trait_exists('T')); var_dump(class_exists('Foo')); ?> --EXPECTF-- -Warning: Can't preload class Foo with unresolved initializer for constant C at %s:%d in Unknown on line 0 +Warning: Can't preload class Foo with unresolved initializer for constant C in %spreload_undef_const_2.inc on line 8 bool(true) bool(false) |