From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: Luiz Capitulino <lcapitulino@redhat.com>
Subject: [Qemu-devel] [PATCH 18/50] error: Infrastructure to track locations for error reporting
Date: Thu, 4 Mar 2010 16:56:39 +0100 [thread overview]
Message-ID: <1267718231-13303-19-git-send-email-armbru@redhat.com> (raw)
In-Reply-To: <1267718231-13303-1-git-send-email-armbru@redhat.com>
New struct Location holds a location. So far, the only location is
LOC_NONE, so this doesn't do anything useful yet.
Passing the current location all over the place would be too
cumbersome. Hide it away in static cur_loc instead, and provide
accessors. Print it in error_report().
Store it in QError, and print it in qerror_print().
Store it in QemuOpt, for use by qemu_opts_foreach(). This makes
error_report() do the right thing when it runs within
qemu_opts_foreach().
We may still have to store it in other data structures holding user
input for better error messages. Left for another day.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
qemu-error.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
qemu-error.h | 16 +++++++++++
qemu-option.c | 7 +++++
qemu-tool.c | 24 ++++++++++++++++
qerror.c | 5 +++-
qerror.h | 4 ++-
6 files changed, 138 insertions(+), 3 deletions(-)
diff --git a/qemu-error.c b/qemu-error.c
index 0a175d8..0d673c5 100644
--- a/qemu-error.c
+++ b/qemu-error.c
@@ -41,15 +41,98 @@ void error_printf(const char *fmt, ...)
va_end(ap);
}
+static Location std_loc = {
+ .kind = LOC_NONE
+};
+static Location *cur_loc = &std_loc;
+
+/*
+ * Push location saved in LOC onto the location stack, return it.
+ * The top of that stack is the current location.
+ * Needs a matching loc_pop().
+ */
+Location *loc_push_restore(Location *loc)
+{
+ assert(!loc->prev);
+ loc->prev = cur_loc;
+ cur_loc = loc;
+ return loc;
+}
+
+/*
+ * Initialize *LOC to "nowhere", push it onto the location stack.
+ * The top of that stack is the current location.
+ * Needs a matching loc_pop().
+ * Return LOC.
+ */
+Location *loc_push_none(Location *loc)
+{
+ loc->kind = LOC_NONE;
+ loc->prev = NULL;
+ return loc_push_restore(loc);
+}
+
+/*
+ * Pop the location stack.
+ * LOC must be the current location, i.e. the top of the stack.
+ */
+Location *loc_pop(Location *loc)
+{
+ assert(cur_loc == loc && loc->prev);
+ cur_loc = loc->prev;
+ loc->prev = NULL;
+ return loc;
+}
+
+/*
+ * Save the current location in LOC, return LOC.
+ */
+Location *loc_save(Location *loc)
+{
+ *loc = *cur_loc;
+ loc->prev = NULL;
+ return loc;
+}
+
+/*
+ * Change the current location to the one saved in LOC.
+ */
+void loc_restore(Location *loc)
+{
+ Location *prev = cur_loc->prev;
+ assert(!loc->prev);
+ *cur_loc = *loc;
+ cur_loc->prev = prev;
+}
+
+/*
+ * Change the current location to "nowhere in particular".
+ */
+void loc_set_none(void)
+{
+ cur_loc->kind = LOC_NONE;
+}
+
+/*
+ * Print current location to current monitor if we have one, else to stderr.
+ */
+void error_print_loc(void)
+{
+ switch (cur_loc->kind) {
+ default: ;
+ }
+}
+
/*
* Print an error message to current monitor if we have one, else to stderr.
- * Appends a newline to the message.
+ * Prepend the current location and append a newline.
* It's wrong to call this in a QMP monitor. Use qerror_report() there.
*/
void error_report(const char *fmt, ...)
{
va_list ap;
+ error_print_loc();
va_start(ap, fmt);
error_vprintf(fmt, ap);
va_end(ap);
diff --git a/qemu-error.h b/qemu-error.h
index 5b05371..a1562aa 100644
--- a/qemu-error.h
+++ b/qemu-error.h
@@ -13,8 +13,24 @@
#ifndef QEMU_ERROR_H
#define QEMU_ERROR_H
+typedef struct Location {
+ /* all members are private to qemu-error.c */
+ enum { LOC_NONE } kind;
+ int num;
+ const void *ptr;
+ struct Location *prev;
+} Location;
+
+Location *loc_push_restore(Location *loc);
+Location *loc_push_none(Location *loc);
+Location *loc_pop(Location *loc);
+Location *loc_save(Location *loc);
+void loc_restore(Location *loc);
+void loc_set_none(void);
+
void error_vprintf(const char *fmt, va_list ap);
void error_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
+void error_print_loc(void);
void error_report(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
void qerror_report_internal(const char *file, int linenr, const char *func,
const char *fmt, ...)
diff --git a/qemu-option.c b/qemu-option.c
index de40bff..ab488e4 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -27,6 +27,7 @@
#include <string.h>
#include "qemu-common.h"
+#include "qemu-error.h"
#include "qemu-option.h"
/*
@@ -483,6 +484,7 @@ struct QemuOpt {
struct QemuOpts {
char *id;
QemuOptsList *list;
+ Location loc;
QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
QTAILQ_ENTRY(QemuOpts) next;
};
@@ -653,6 +655,7 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exist
opts->id = qemu_strdup(id);
}
opts->list = list;
+ loc_save(&opts->loc);
QTAILQ_INIT(&opts->head);
QTAILQ_INSERT_TAIL(&list->head, opts, next);
return opts;
@@ -810,13 +813,17 @@ int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
int abort_on_failure)
{
+ Location loc;
QemuOpts *opts;
int rc = 0;
+ loc_push_none(&loc);
QTAILQ_FOREACH(opts, &list->head, next) {
+ loc_restore(&opts->loc);
rc |= func(opts, opaque);
if (abort_on_failure && rc != 0)
break;
}
+ loc_pop(&loc);
return rc;
}
diff --git a/qemu-tool.c b/qemu-tool.c
index 939049a..97ca949 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -104,6 +104,30 @@ int64_t qemu_get_clock(QEMUClock *clock)
return (tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000)) / 1000000;
}
+Location *loc_push_restore(Location *loc)
+{
+ return loc;
+}
+
+Location *loc_push_none(Location *loc)
+{
+ return loc;
+}
+
+Location *loc_pop(Location *loc)
+{
+ return loc;
+}
+
+Location *loc_save(Location *loc)
+{
+ return loc;
+}
+
+void loc_restore(Location *loc)
+{
+}
+
void error_report(const char *fmt, ...)
{
va_list args;
diff --git a/qerror.c b/qerror.c
index a6f0213..b400480 100644
--- a/qerror.c
+++ b/qerror.c
@@ -224,6 +224,7 @@ QError *qerror_from_info(const char *file, int linenr, const char *func,
QError *qerr;
qerr = qerror_new();
+ loc_save(&qerr->loc);
qerr->linenr = linenr;
qerr->file = file;
qerr->func = func;
@@ -321,10 +322,12 @@ QString *qerror_human(const QError *qerror)
* it uses error_report() for this, so that the output is routed to the right
* place (ie. stderr or Monitor's device).
*/
-void qerror_print(const QError *qerror)
+void qerror_print(QError *qerror)
{
QString *qstring = qerror_human(qerror);
+ loc_push_restore(&qerror->loc);
error_report("%s", qstring_get_str(qstring));
+ loc_pop(&qerror->loc);
QDECREF(qstring);
}
diff --git a/qerror.h b/qerror.h
index ee59615..f25be1b 100644
--- a/qerror.h
+++ b/qerror.h
@@ -14,6 +14,7 @@
#include "qdict.h"
#include "qstring.h"
+#include "qemu-error.h"
#include <stdarg.h>
typedef struct QErrorStringTable {
@@ -24,6 +25,7 @@ typedef struct QErrorStringTable {
typedef struct QError {
QObject_HEAD;
QDict *error;
+ Location loc;
int linenr;
const char *file;
const char *func;
@@ -34,7 +36,7 @@ QError *qerror_new(void);
QError *qerror_from_info(const char *file, int linenr, const char *func,
const char *fmt, va_list *va);
QString *qerror_human(const QError *qerror);
-void qerror_print(const QError *qerror);
+void qerror_print(QError *qerror);
QError *qobject_to_qerror(const QObject *obj);
/*
--
1.6.6.1
next prev parent reply other threads:[~2010-03-04 15:57 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-04 15:56 [Qemu-devel] [PATCH 00/50] Convert device_add to QObject / QError Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 01/50] usb: Remove disabled monitor_printf() in usb_read_file() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 02/50] savevm: Fix -loadvm to report errors to stderr, not the monitor Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 03/50] pc: Fix error reporting for -boot once Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 04/50] pc: Factor common code out of pc_boot_set() and cmos_init() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 05/50] tools: Remove unused cur_mon from qemu-tool.c Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 06/50] monitor: Separate "default monitor" and "current monitor" cleanly Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 07/50] block: Simplify usb_msd_initfn() test for "can read bdrv key" Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 08/50] monitor: Factor monitor_set_error() out of qemu_error_internal() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 09/50] error: Move qemu_error() & friends from monitor.c to own file Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 10/50] error: Simplify error sink setup Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 11/50] error: Move qemu_error & friends into their own header Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 12/50] error: New error_printf() and error_vprintf() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 13/50] error: Don't abuse qemu_error() for non-error in qdev_device_help() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 14/50] error: Don't abuse qemu_error() for non-error in qbus_find() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 15/50] error: Don't abuse qemu_error() for non-error in scsi_hot_add() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 16/50] error: Replace qemu_error() by error_report() Markus Armbruster
2010-03-13 2:34 ` [Qemu-devel] " Luiz Capitulino
2010-03-04 15:56 ` [Qemu-devel] [PATCH 17/50] error: Rename qemu_error_new() to qerror_report() Markus Armbruster
2010-03-04 15:56 ` Markus Armbruster [this message]
2010-03-04 15:56 ` [Qemu-devel] [PATCH 19/50] error: Include the program name in error messages to stderr Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 20/50] error: Track locations in configuration files Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 21/50] QemuOpts: Fix qemu_config_parse() to catch file read errors Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 22/50] error: Track locations on command line Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 23/50] qdev: Fix -device and device_add to handle unsuitable bus gracefully Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 24/50] qdev: Factor qdev_create_from_info() out of qdev_create() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 25/50] qdev: Hide "no_user" devices from users Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 26/50] qdev: Hide "ptr" properties " Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 27/50] monitor: New monitor_cur_is_qmp() Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 28/50] error: Let converted handlers print in human monitor Markus Armbruster
2010-03-04 20:50 ` [Qemu-devel] " Luiz Capitulino
2010-03-04 21:06 ` Markus Armbruster
2010-03-04 21:14 ` Luiz Capitulino
2010-03-05 15:43 ` Luiz Capitulino
2010-03-05 16:43 ` Markus Armbruster
2010-03-08 13:41 ` Luiz Capitulino
2010-03-04 15:56 ` [Qemu-devel] [PATCH 29/50] error: Polish human-readable error descriptions Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 30/50] error: New QERR_PROPERTY_NOT_FOUND Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 31/50] error: New QERR_PROPERTY_VALUE_BAD Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 32/50] qdev: convert setting device properties to QError Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 33/50] qdev: Relax parsing of bus option Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 34/50] error: New QERR_BUS_NOT_FOUND Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 35/50] error: New QERR_DEVICE_MULTIPLE_BUSSES Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 36/50] error: New QERR_DEVICE_NO_BUS Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 37/50] qdev: Convert qbus_find() to QError Markus Armbruster
2010-03-04 15:56 ` [Qemu-devel] [PATCH 38/50] error: New error_printf_unless_qmp() Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 39/50] error: New QERR_BAD_BUS_FOR_DEVICE Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 40/50] error: New QERR_BUS_NO_HOTPLUG Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 41/50] error: New QERR_DEVICE_INIT_FAILED Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 42/50] error: New QERR_NO_BUS_FOR_DEVICE Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 43/50] Revert "qdev: Use QError for 'device not found' error" Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 44/50] error: Convert do_device_add() to QError Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 45/50] qemu-option: Functions to convert to/from QDict Markus Armbruster
2010-03-04 20:55 ` [Qemu-devel] " Luiz Capitulino
2010-03-04 21:12 ` Markus Armbruster
2010-03-04 21:17 ` Luiz Capitulino
2010-03-04 15:57 ` [Qemu-devel] [PATCH 46/50] qemu-option: Move the implied first name into QemuOptsList Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 47/50] qemu-option: Rename find_list() to qemu_find_opts() & external linkage Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 48/50] monitor: New argument type 'O' Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 49/50] monitor: Use argument type 'O' for device_add Markus Armbruster
2010-03-04 15:57 ` [Qemu-devel] [PATCH 50/50] monitor: convert do_device_add() to QObject Markus Armbruster
2010-03-16 18:31 ` [Qemu-devel] [PULL v2] Convert device_add to QObject / QError Markus Armbruster
2010-03-17 15:28 ` Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1267718231-13303-19-git-send-email-armbru@redhat.com \
--to=armbru@redhat.com \
--cc=lcapitulino@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).