summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-03-26 15:46:09 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-03-26 15:47:00 +0100
commit0122f395c7dc5afb9feb3e2dcd11bb90e7433948 (patch)
treefad0964b53bcfb35d23b2da2dbd2ad79bd66d814
parenta9b01b60d89506b4f661b7108836d217158e83a2 (diff)
downloadphp-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.c166
-rw-r--r--Zend/zend.h14
-rw-r--r--ext/opcache/ZendAccelerator.c18
-rw-r--r--ext/opcache/tests/preload_004.phpt2
-rw-r--r--ext/opcache/tests/preload_009.phpt2
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)