Error reporting patches for 2016-02-09
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWud3JAAoJEDhwtADrkYZTY8cP/RxodWGC/4ftfSebRTgO9lk7 Dn5BzuUjnz2IGX3iGVx/PAyc5DMTl1qiZ71P4yOvDl6haPoB6WeQnYHKhORE6NFK WzqsKtJjdt0fpZSHDbiivniVlc3E33js6TqXjeylBh+YbHTbJjFzUUjsV3urOI5+ kDG8fZUNdIOxnXAH2Vv62FXbdg3YL1bQBCNf1MsG8QZ0Z6Pp4s5YyUtzYWYacUbO R3VMgDAOp7T4ZD2xMR0fafTQr1NqpvRz/W7WtkHK6Ix5OpwKbP3daYYcSSxK6iZv gqCFhIPlbFJNZ1g0s4cGBxP5sl5I7Hr77Q29htc+UER/LVR9wrNXVfbDnLZ2Ajqh 7q5wfGQGxcZZwb5cmFIVZrZwdo0vy5cNE7WPL9hWK9WlAwBMbI6x8db06jd6WsVJ 3GpG9La54Dw+f84bElnsJTaw4v0M6qjcnxklffaWIsG88Rslwsqn30DrTerIE20I cBExrD8GCwr91eda7jGZSUSHlJtwGRK3EhIW3QBnKx+KMcJ9nC3+nDa6UIRY53x9 9RDgMvI2/yxk8vEaXhLdbajGme0fOfCV+pNG6cj7MulnHyEryZNhRPNMGHrQ4hP6 gOLVzW7C/Ulfd/l1OsRUXRD15nQZHdigUhXiXgSrCkv67kWPfZEEkJseQw5C8CQI vGXWz2g0YCnAgcXpOYII =62Ar -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2016-02-09' into staging Error reporting patches for 2016-02-09 # gpg: Signature made Tue 09 Feb 2016 12:38:33 GMT using RSA key ID EB918653 # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" * remotes/armbru/tags/pull-error-2016-02-09: HACKING: Add a section on error handling and reporting error: Improve documentation some more Use error_fatal to simplify obvious fatal errors (again) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
84c0781103
55
HACKING
55
HACKING
@ -157,3 +157,58 @@ painful. These are:
|
||||
* you may assume that integers are 2s complement representation
|
||||
* you may assume that right shift of a signed integer duplicates
|
||||
the sign bit (ie it is an arithmetic shift, not a logical shift)
|
||||
|
||||
7. Error handling and reporting
|
||||
|
||||
7.1 Reporting errors to the human user
|
||||
|
||||
Do not use printf(), fprintf() or monitor_printf(). Instead, use
|
||||
error_report() or error_vreport() from error-report.h. This ensures the
|
||||
error is reported in the right place (current monitor or stderr), and in
|
||||
a uniform format.
|
||||
|
||||
Use error_printf() & friends to print additional information.
|
||||
|
||||
error_report() prints the current location. In certain common cases
|
||||
like command line parsing, the current location is tracked
|
||||
automatically. To manipulate it manually, use the loc_*() from
|
||||
error-report.h.
|
||||
|
||||
7.2 Propagating errors
|
||||
|
||||
An error can't always be reported to the user right where it's detected,
|
||||
but often needs to be propagated up the call chain to a place that can
|
||||
handle it. This can be done in various ways.
|
||||
|
||||
The most flexible one is Error objects. See error.h for usage
|
||||
information.
|
||||
|
||||
Use the simplest suitable method to communicate success / failure to
|
||||
callers. Stick to common methods: non-negative on success / -1 on
|
||||
error, non-negative / -errno, non-null / null, or Error objects.
|
||||
|
||||
Example: when a function returns a non-null pointer on success, and it
|
||||
can fail only in one way (as far as the caller is concerned), returning
|
||||
null on failure is just fine, and certainly simpler and a lot easier on
|
||||
the eyes than propagating an Error object through an Error ** parameter.
|
||||
|
||||
Example: when a function's callers need to report details on failure
|
||||
only the function really knows, use Error **, and set suitable errors.
|
||||
|
||||
Do not report an error to the user when you're also returning an error
|
||||
for somebody else to handle. Leave the reporting to the place that
|
||||
consumes the error returned.
|
||||
|
||||
7.3 Handling errors
|
||||
|
||||
Calling exit() is fine when handling configuration errors during
|
||||
startup. It's problematic during normal operation. In particular,
|
||||
monitor commands should never exit().
|
||||
|
||||
Do not call exit() or abort() to handle an error that can be triggered
|
||||
by the guest (e.g., some unimplemented corner case in guest code
|
||||
translation or device emulation). Guests should not be able to
|
||||
terminate QEMU.
|
||||
|
||||
Note that &error_fatal is just another way to exit(1), and &error_abort
|
||||
is just another way to abort().
|
||||
|
@ -65,7 +65,6 @@ static struct arm_boot_info imx25_pdk_binfo;
|
||||
static void imx25_pdk_init(MachineState *machine)
|
||||
{
|
||||
IMX25PDK *s = g_new0(IMX25PDK, 1);
|
||||
Error *err = NULL;
|
||||
unsigned int ram_size;
|
||||
unsigned int alias_offset;
|
||||
int i;
|
||||
@ -74,11 +73,7 @@ static void imx25_pdk_init(MachineState *machine)
|
||||
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
|
||||
&error_abort);
|
||||
|
||||
object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
|
||||
if (err != NULL) {
|
||||
error_report_err(err);
|
||||
exit(1);
|
||||
}
|
||||
object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
|
||||
|
||||
/* We need to initialize our memory */
|
||||
if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
|
||||
|
@ -64,7 +64,6 @@ static struct arm_boot_info kzm_binfo = {
|
||||
static void kzm_init(MachineState *machine)
|
||||
{
|
||||
IMX31KZM *s = g_new0(IMX31KZM, 1);
|
||||
Error *err = NULL;
|
||||
unsigned int ram_size;
|
||||
unsigned int alias_offset;
|
||||
unsigned int i;
|
||||
@ -73,11 +72,7 @@ static void kzm_init(MachineState *machine)
|
||||
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
|
||||
&error_abort);
|
||||
|
||||
object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
|
||||
if (err != NULL) {
|
||||
error_report_err(err);
|
||||
exit(1);
|
||||
}
|
||||
object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
|
||||
|
||||
/* Check the amount of memory is compatible with the SOC */
|
||||
if (machine->ram_size > (FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE)) {
|
||||
|
@ -30,18 +30,13 @@
|
||||
static void netduino2_init(MachineState *machine)
|
||||
{
|
||||
DeviceState *dev;
|
||||
Error *err = NULL;
|
||||
|
||||
dev = qdev_create(NULL, TYPE_STM32F205_SOC);
|
||||
if (machine->kernel_filename) {
|
||||
qdev_prop_set_string(dev, "kernel-filename", machine->kernel_filename);
|
||||
}
|
||||
qdev_prop_set_string(dev, "cpu-model", "cortex-m3");
|
||||
object_property_set_bool(OBJECT(dev), true, "realized", &err);
|
||||
if (err != NULL) {
|
||||
error_report_err(err);
|
||||
exit(1);
|
||||
}
|
||||
object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
|
||||
}
|
||||
|
||||
static void netduino2_machine_init(MachineClass *mc)
|
||||
|
@ -32,7 +32,6 @@ static void xlnx_ep108_init(MachineState *machine)
|
||||
{
|
||||
XlnxEP108 *s = g_new0(XlnxEP108, 1);
|
||||
int i;
|
||||
Error *err = NULL;
|
||||
uint64_t ram_size = machine->ram_size;
|
||||
|
||||
/* Create the memory region to pass to the SoC */
|
||||
@ -58,11 +57,7 @@ static void xlnx_ep108_init(MachineState *machine)
|
||||
object_property_set_link(OBJECT(&s->soc), OBJECT(&s->ddr_ram),
|
||||
"ddr-ram", &error_abort);
|
||||
|
||||
object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
|
||||
if (err) {
|
||||
error_report_err(err);
|
||||
exit(1);
|
||||
}
|
||||
object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
|
||||
|
||||
for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
|
||||
SSIBus *spi_bus;
|
||||
|
@ -27,11 +27,11 @@
|
||||
* error_setg(&err, "invalid quark\n"
|
||||
* "Valid quarks are up, down, strange, charm, top, bottom.");
|
||||
*
|
||||
* Report an error to stderr:
|
||||
* Report an error to the current monitor if we have one, else stderr:
|
||||
* error_report_err(err);
|
||||
* This frees the error object.
|
||||
*
|
||||
* Report an error to stderr with additional text prepended:
|
||||
* Likewise, but with additional text prepended:
|
||||
* error_reportf_err(err, "Could not frobnicate '%s': ", name);
|
||||
*
|
||||
* Report an error somewhere else:
|
||||
@ -162,6 +162,9 @@ ErrorClass error_get_class(const Error *err);
|
||||
* human-readable error message is made from printf-style @fmt, ...
|
||||
* The resulting message should be a single phrase, with no newline or
|
||||
* trailing punctuation.
|
||||
* Please don't error_setg(&error_fatal, ...), use error_report() and
|
||||
* exit(), because that's more obvious.
|
||||
* Likewise, don't error_setg(&error_abort, ...), use assert().
|
||||
*/
|
||||
#define error_setg(errp, fmt, ...) \
|
||||
error_setg_internal((errp), __FILE__, __LINE__, __func__, \
|
||||
@ -213,6 +216,8 @@ void error_setg_win32_internal(Error **errp,
|
||||
* the error object.
|
||||
* Else, move the error object from @local_err to *@dst_errp.
|
||||
* On return, @local_err is invalid.
|
||||
* Please don't error_propagate(&error_fatal, ...), use
|
||||
* error_report_err() and exit(), because that's more obvious.
|
||||
*/
|
||||
void error_propagate(Error **dst_errp, Error *local_err);
|
||||
|
||||
@ -291,12 +296,14 @@ void error_set_internal(Error **errp,
|
||||
GCC_FMT_ATTR(6, 7);
|
||||
|
||||
/*
|
||||
* Pass to error_setg() & friends to abort() on error.
|
||||
* Special error destination to abort on error.
|
||||
* See error_setg() and error_propagate() for details.
|
||||
*/
|
||||
extern Error *error_abort;
|
||||
|
||||
/*
|
||||
* Pass to error_setg() & friends to exit(1) on error.
|
||||
* Special error destination to exit(1) on error.
|
||||
* See error_setg() and error_propagate() for details.
|
||||
*/
|
||||
extern Error *error_fatal;
|
||||
|
||||
|
7
vl.c
7
vl.c
@ -4557,12 +4557,7 @@ int main(int argc, char **argv, char **envp)
|
||||
net_check_clients();
|
||||
|
||||
if (boot_once) {
|
||||
Error *local_err = NULL;
|
||||
qemu_boot_set(boot_once, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
exit(1);
|
||||
}
|
||||
qemu_boot_set(boot_once, &error_fatal);
|
||||
qemu_register_reset(restore_boot_order, g_strdup(boot_order));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user