Adds a special error object that transforms error messages into immediately reported warnings.
Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> --- include/qapi/error.h | 20 ++++++++++++++++++++ util/error.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/include/qapi/error.h b/include/qapi/error.h index 4d42cdc..9b7600c 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -57,6 +57,9 @@ * Call a function treating errors as fatal: * foo(arg, &error_fatal); * + * Call a function immediately showing all errors as warnings: + * foo(arg, &error_warn); + * * Receive an error and pass it on to the caller: * Error *err = NULL; * foo(arg, &err); @@ -108,6 +111,7 @@ ErrorClass error_get_class(const Error *err); * then. * If @errp is &error_abort, print a suitable message and abort(). * If @errp is &error_fatal, print a suitable message and exit(1). + * If @errp is &error_warn, print a suitable message. * If @errp is anything else, *@errp must be NULL. * The new error's class is ERROR_CLASS_GENERIC_ERROR, and its * human-readable error message is made from printf-style @fmt, ... @@ -158,6 +162,7 @@ void error_setg_win32_internal(Error **errp, * abort(). * Else, if @dst_errp is &error_fatal, print a suitable message and * exit(1). + * Else, if @dst_errp is &error_warn, print a suitable message. * Else, if @dst_errp already contains an error, ignore this one: free * the error object. * Else, move the error object from @local_err to *@dst_errp. @@ -218,12 +223,27 @@ void error_set_internal(Error **errp, /* * Pass to error_setg() & friends to abort() on error. + * + * WARNING: Do _not_ use for errors that are (or can be) triggered by guest code + * (e.g., some unimplimented corner case in guest code translation or + * device code). Otherwise that can be abused by guest code to + * terminate QEMU. */ extern Error *error_abort; /* * Pass to error_setg() & friends to exit(1) on error. + * + * WARNING: Do _not_ use for errors that are (or can be) triggered by guest code + * (e.g., some unimplimented corner case in guest code translation or + * device code). Otherwise that can be abused by guest code to + * terminate QEMU. */ extern Error *error_fatal; +/* + * Pass to error_setg() & friends to immediately show an error as a warning. + */ +extern Error *error_warn; + #endif diff --git a/util/error.c b/util/error.c index 80c89a2..85170e54 100644 --- a/util/error.c +++ b/util/error.c @@ -15,6 +15,7 @@ #include "qemu-common.h" #include "qapi/error.h" #include "qemu/error-report.h" +#include "qemu/timer.h" struct Error { @@ -27,8 +28,9 @@ struct Error Error *error_abort; Error *error_fatal; +Error *error_warn; -static void error_handle_fatal(Error **errp, Error *err) +static bool error_handle_fatal(Error **errp, Error *err) { if (errp == &error_abort) { fprintf(stderr, "Unexpected error in %s() at %s:%d:\n", @@ -40,6 +42,20 @@ static void error_handle_fatal(Error **errp, Error *err) error_report_err(err); exit(1); } + + if (errp == &error_warn) { + /* cannot use error_report_err() because it adds newlines */ + error_report("warning: [%s() at %s:%d] %s", + err->func, err->src, err->line, err->msg); + if (err->hint) { + error_printf_unless_qmp("warning: [%s() at %s:%d] %s", + err->func, err->src, err->line, + err->hint->str); + } + return true; + } else { + return false; + } } static void error_setv(Error **errp, @@ -61,10 +77,10 @@ static void error_setv(Error **errp, err->line = line; err->func = func; - error_handle_fatal(errp, err); - *errp = err; - - errno = saved_errno; + if (!error_handle_fatal(errp, err)) { + *errp = err; + errno = saved_errno; + } } void error_set_internal(Error **errp, @@ -232,10 +248,11 @@ void error_propagate(Error **dst_errp, Error *local_err) if (!local_err) { return; } - error_handle_fatal(dst_errp, local_err); - if (dst_errp && !*dst_errp) { - *dst_errp = local_err; - } else { - error_free(local_err); + if (!error_handle_fatal(dst_errp, local_err)) { + if (dst_errp && !*dst_errp) { + *dst_errp = local_err; + } else { + error_free(local_err); + } } }