qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/2] error: Distinguish critical and non-critical er


From: Peter Maydell
Subject: [Qemu-devel] [PATCH 1/2] error: Distinguish critical and non-critical errors
Date: Fri, 19 Oct 2012 18:19:05 +0100

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 <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]