From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:50698) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TPGLS-0003ih-Q3 for qemu-devel@nongnu.org; Fri, 19 Oct 2012 13:26:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TPGLL-0006TP-6p for qemu-devel@nongnu.org; Fri, 19 Oct 2012 13:26:50 -0400 Received: from 38.0.169.217.in-addr.arpa ([217.169.0.38]:50507 helo=mnementh.archaic.org.uk) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TPGLK-0006RA-VV for qemu-devel@nongnu.org; Fri, 19 Oct 2012 13:26:43 -0400 From: Peter Maydell Date: Fri, 19 Oct 2012 18:19:05 +0100 Message-Id: <1350667146-26273-2-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1350667146-26273-1-git-send-email-peter.maydell@linaro.org> References: <1350667146-26273-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [PATCH 1/2] error: Distinguish critical and non-critical errors List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Anthony Liguori , patches@linaro.org Add the concept of a 'critical' error, which is one that must not be ignored. If, at the point when the error is raised or at any subsequent point while propagating it, we find that we would be throwing away the error because of a NULL Error**, we print the error message to stderr and abort(). Signed-off-by: Peter Maydell --- error.c | 38 ++++++++++++++++++++++++++++++++++---- error.h | 12 ++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/error.c b/error.c index 1f05fc4..3f76fd5 100644 --- a/error.c +++ b/error.c @@ -21,12 +21,13 @@ struct Error { char *msg; ErrorClass err_class; + bool is_critical; }; -void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) +static void do_error_set(Error **errp, ErrorClass err_class, + const char *fmt, va_list ap) { Error *err; - va_list ap; if (errp == NULL) { return; @@ -35,14 +36,38 @@ void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) err = g_malloc0(sizeof(*err)); - va_start(ap, fmt); err->msg = g_strdup_vprintf(fmt, ap); - va_end(ap); err->err_class = err_class; *errp = err; } +void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + do_error_set(errp, err_class, fmt, ap); + va_end(ap); +} + +void error_set_critical(Error **errp, ErrorClass err_class, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (!errp) { + /* Critical error which would be ignored: print and abort now */ + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + abort(); + } + + do_error_set(errp, err_class, fmt, ap); + (*errp)->is_critical = true; + + va_end(ap); +} + Error *error_copy(const Error *err) { Error *err_new; @@ -50,6 +75,7 @@ Error *error_copy(const Error *err) err_new = g_malloc0(sizeof(*err)); err_new->msg = g_strdup(err->msg); err_new->err_class = err->err_class; + err_new->is_critical = err->is_critical; return err_new; } @@ -82,6 +108,10 @@ void error_propagate(Error **dst_err, Error *local_err) if (dst_err && !*dst_err) { *dst_err = local_err; } else if (local_err) { + if (local_err->is_critical) { + fprintf(stderr, "%s\n", error_get_pretty(local_err)); + abort(); + } error_free(local_err); } } diff --git a/error.h b/error.h index da7fed3..4be0893 100644 --- a/error.h +++ b/error.h @@ -36,6 +36,18 @@ void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__) /** + * Same as error_set(), but mark the error as critical + */ +void error_set_critical(Error **err, ErrorClass err_class, + const char *fmt, ...) GCC_FMT_ATTR(3, 4); + +/** + * Same as error_setg(), but mark the error as critical + */ +#define error_setg_critical(err, fmt, ...) \ + error_set_critical(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__) + +/** * Returns true if an indirect pointer to an error is pointing to a valid * error object. */ -- 1.7.9.5