All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
@ 2016-09-07  6:06 Peter Xu
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 1/4] error-report: provide error_report_fatal() Peter Xu
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Peter Xu @ 2016-09-07  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, peter.maydell, pbonzini, famz, peterx

v4 changes:
- remove two standard headers since they are included in osdep.h
  already [Fam]
- make sure it passes build on all platforms (no --target-list
  specified during configure)

v3 changes:
- implement error_report_fatal using function [Markus]
- provide error_report_abort as well in seperate patch [Markus, Fam]

We have many use cases that first print some error messages, then
quit (by either exit() or abort()). This series introduce two helper
functions for that.

The old formats are mostly one of the following:

Case one:

  error_report(...);
  exit(1|EXIT_FAILURE) | abort();

Case two:

  error_setg(&error_{fatal|abort}, ...);

And we can convert either of the above cases into:

  error_report_{fatal|abort}(...);

Two coccinelle scripts are created to help automate the work, plus
some manual tweaks:

1. very long strings, fix for over-80-chars issues, to make sure it
   passes checkpatch.pl.

2. add "return XXX" for some non-void retcode functions.

The first two patches introduce the functions. The latter two apply
them.

Peter Xu (4):
  error-report: provide error_report_fatal()
  error-report: provide error_report_abort()
  error-report: leverage error_report_fatal()
  error-report: leverage error_report_abort()

 arch_init.c                                 |   8 +-
 block/qcow2.c                               |   4 +-
 bootdevice.c                                |   4 +-
 cpus.c                                      |   3 +-
 device_tree.c                               |  61 +++---
 hw/9pfs/9p.c                                |   3 +-
 hw/alpha/dp264.c                            |  14 +-
 hw/arm/armv7m.c                             |   3 +-
 hw/arm/digic_boards.c                       |   6 +-
 hw/arm/fsl-imx6.c                           |   5 +-
 hw/arm/highbank.c                           |   6 +-
 hw/arm/raspi.c                              |   7 +-
 hw/arm/sabrelite.c                          |   9 +-
 hw/arm/strongarm.c                          |   6 +-
 hw/arm/sysbus-fdt.c                         |  41 ++--
 hw/arm/vexpress.c                           |  14 +-
 hw/arm/virt.c                               |  45 ++---
 hw/arm/xlnx-ep108.c                         |  10 +-
 hw/block/fdc.c                              |   6 +-
 hw/block/tc58128.c                          |   3 +-
 hw/block/virtio-blk.c                       |   9 +-
 hw/char/exynos4210_uart.c                   |   9 +-
 hw/core/machine.c                           |   7 +-
 hw/core/platform-bus.c                      |   8 +-
 hw/i386/intel_iommu.c                       |   5 +-
 hw/i386/kvm/pci-assign.c                    |   4 +-
 hw/i386/pc.c                                |  36 ++--
 hw/i386/pc_piix.c                           |   3 +-
 hw/i386/x86-iommu.c                         |   5 +-
 hw/ide/core.c                               |   5 +-
 hw/intc/ioapic.c                            |   5 +-
 hw/intc/xics.c                              |   5 +-
 hw/intc/xics_kvm.c                          |  17 +-
 hw/m68k/an5206.c                            |   3 +-
 hw/microblaze/boot.c                        |   5 +-
 hw/mips/mips_fulong2e.c                     |   3 +-
 hw/mips/mips_jazz.c                         |   3 +-
 hw/mips/mips_malta.c                        |  26 ++-
 hw/mips/mips_mipssim.c                      |   6 +-
 hw/net/virtio-net.c                         |  28 ++-
 hw/nvram/fw_cfg.c                           |   5 +-
 hw/pci/pci.c                                |   8 +-
 hw/ppc/e500.c                               |   5 +-
 hw/ppc/mac_newworld.c                       |  14 +-
 hw/ppc/mac_oldworld.c                       |  18 +-
 hw/ppc/mpc8544ds.c                          |   4 +-
 hw/ppc/ppc405_boards.c                      |  14 +-
 hw/ppc/prep.c                               |  11 +-
 hw/ppc/spapr.c                              |  89 ++++-----
 hw/ppc/spapr_drc.c                          |   2 +-
 hw/ppc/virtex_ml507.c                       |   5 +-
 hw/scsi/vhost-scsi.c                        |  11 +-
 hw/scsi/virtio-scsi.c                       |  10 +-
 hw/sh4/shix.c                               |   3 +-
 hw/smbios/smbios.c                          |  42 ++---
 hw/sparc/sun4m.c                            |  19 +-
 hw/tricore/tricore_testboard.c              |   8 +-
 hw/unicore32/puv3.c                         |   9 +-
 hw/vfio/platform.c                          |  10 +-
 hw/virtio/virtio.c                          |  45 ++---
 hw/xtensa/sim.c                             |   5 +-
 hw/xtensa/xtfpga.c                          |  17 +-
 include/qemu/error-report.h                 |   2 +
 net/netmap.c                                |   5 +-
 net/tap-linux.c                             |  10 +-
 numa.c                                      |  22 +--
 qemu-img.c                                  |  16 +-
 qemu-io.c                                   |   9 +-
 qemu-nbd.c                                  | 116 +++++-------
 replay/replay-char.c                        |   9 +-
 replay/replay-events.c                      |  12 +-
 replay/replay-internal.c                    |   4 +-
 replay/replay-time.c                        |   5 +-
 replay/replay.c                             |   9 +-
 scripts/coccinelle/error_report_abort.cocci |  14 ++
 scripts/coccinelle/error_report_fatal.cocci |  20 ++
 target-arm/machine.c                        |   5 +-
 target-i386/kvm.c                           |  10 +-
 target-ppc/kvm.c                            |   7 +-
 target-ppc/translate_init.c                 |   3 +-
 target-s390x/cpu.c                          |   5 +-
 target-s390x/kvm.c                          |   8 +-
 target-s390x/mmu_helper.c                   |   5 +-
 trace/control.c                             |   6 +-
 ui/spice-core.c                             |  43 ++---
 util/qemu-error.c                           |  22 +++
 vl.c                                        | 279 +++++++++++-----------------
 xen-hvm.c                                   |   3 +-
 88 files changed, 622 insertions(+), 831 deletions(-)
 create mode 100644 scripts/coccinelle/error_report_abort.cocci
 create mode 100644 scripts/coccinelle/error_report_fatal.cocci

-- 
2.7.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 1/4] error-report: provide error_report_fatal()
  2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
@ 2016-09-07  6:06 ` Peter Xu
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 2/4] error-report: provide error_report_abort() Peter Xu
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Peter Xu @ 2016-09-07  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, peter.maydell, pbonzini, famz, peterx

There are many places in current QEMU codes that needs to print some
error and then quit QEMU. Provide a new function for it.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 include/qemu/error-report.h |  1 +
 util/qemu-error.c           | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index 499ec8b..eb8260e 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -36,6 +36,7 @@ void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 void error_set_progname(const char *argv0);
 void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
 void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
+void error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 const char *error_get_progname(void);
 extern bool enable_timestamp_msg;
 
diff --git a/util/qemu-error.c b/util/qemu-error.c
index 1ef3566..684f543 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -237,3 +237,14 @@ void error_report(const char *fmt, ...)
     error_vreport(fmt, ap);
     va_end(ap);
 }
+
+void error_report_fatal(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    error_vreport(fmt, ap);
+    va_end(ap);
+
+    exit(1);
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 2/4] error-report: provide error_report_abort()
  2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 1/4] error-report: provide error_report_fatal() Peter Xu
@ 2016-09-07  6:06 ` Peter Xu
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 3/4] error-report: leverage error_report_fatal() Peter Xu
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Peter Xu @ 2016-09-07  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, peter.maydell, pbonzini, famz, peterx

A twin for error_report_fatal(), for programming errors.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 include/qemu/error-report.h |  1 +
 util/qemu-error.c           | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index eb8260e..51a6f31 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -37,6 +37,7 @@ void error_set_progname(const char *argv0);
 void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
 void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 void error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
+void error_report_abort(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 const char *error_get_progname(void);
 extern bool enable_timestamp_msg;
 
diff --git a/util/qemu-error.c b/util/qemu-error.c
index 684f543..59726ab 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -248,3 +248,14 @@ void error_report_fatal(const char *fmt, ...)
 
     exit(1);
 }
+
+void error_report_abort(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    error_vreport(fmt, ap);
+    va_end(ap);
+
+    abort();
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 3/4] error-report: leverage error_report_fatal()
  2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 1/4] error-report: provide error_report_fatal() Peter Xu
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 2/4] error-report: provide error_report_abort() Peter Xu
@ 2016-09-07  6:06 ` Peter Xu
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 4/4] error-report: leverage error_report_abort() Peter Xu
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Peter Xu @ 2016-09-07  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, peter.maydell, pbonzini, famz, peterx

Currently there are two kinds of users for error_report_fatal():

Case 1:

  error_report(...);
  exit(1|EXIT_FAILURE);

Case 2:

  error_setg(&error_fatal, ...);

This patch converts all the above cases to use the new
error_report_fatal() interface.

Script error_report_fatal.cocci is created to help automate the work.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 arch_init.c                                 |   8 +-
 bootdevice.c                                |   4 +-
 cpus.c                                      |   3 +-
 device_tree.c                               |  61 +++----
 hw/9pfs/9p.c                                |   3 +-
 hw/alpha/dp264.c                            |  14 +-
 hw/arm/armv7m.c                             |   3 +-
 hw/arm/digic_boards.c                       |   6 +-
 hw/arm/fsl-imx6.c                           |   5 +-
 hw/arm/highbank.c                           |   6 +-
 hw/arm/raspi.c                              |   7 +-
 hw/arm/sabrelite.c                          |   9 +-
 hw/arm/strongarm.c                          |   6 +-
 hw/arm/sysbus-fdt.c                         |  41 ++---
 hw/arm/vexpress.c                           |  14 +-
 hw/arm/virt.c                               |  45 ++---
 hw/arm/xlnx-ep108.c                         |  10 +-
 hw/block/tc58128.c                          |   3 +-
 hw/block/virtio-blk.c                       |   9 +-
 hw/char/exynos4210_uart.c                   |   9 +-
 hw/core/machine.c                           |   7 +-
 hw/core/platform-bus.c                      |   8 +-
 hw/i386/intel_iommu.c                       |   5 +-
 hw/i386/pc.c                                |  36 ++--
 hw/i386/pc_piix.c                           |   3 +-
 hw/i386/x86-iommu.c                         |   5 +-
 hw/ide/core.c                               |   5 +-
 hw/intc/ioapic.c                            |   5 +-
 hw/intc/xics_kvm.c                          |  17 +-
 hw/m68k/an5206.c                            |   3 +-
 hw/microblaze/boot.c                        |   5 +-
 hw/mips/mips_fulong2e.c                     |   3 +-
 hw/mips/mips_jazz.c                         |   3 +-
 hw/mips/mips_malta.c                        |  26 ++-
 hw/mips/mips_mipssim.c                      |   6 +-
 hw/net/virtio-net.c                         |  28 ++-
 hw/nvram/fw_cfg.c                           |   5 +-
 hw/pci/pci.c                                |   5 +-
 hw/ppc/e500.c                               |   5 +-
 hw/ppc/mac_newworld.c                       |  14 +-
 hw/ppc/mac_oldworld.c                       |  18 +-
 hw/ppc/mpc8544ds.c                          |   4 +-
 hw/ppc/ppc405_boards.c                      |  14 +-
 hw/ppc/prep.c                               |  11 +-
 hw/ppc/spapr.c                              |  89 ++++-----
 hw/ppc/virtex_ml507.c                       |   5 +-
 hw/scsi/vhost-scsi.c                        |  11 +-
 hw/scsi/virtio-scsi.c                       |  10 +-
 hw/sh4/shix.c                               |   3 +-
 hw/smbios/smbios.c                          |  42 ++---
 hw/sparc/sun4m.c                            |  19 +-
 hw/tricore/tricore_testboard.c              |   8 +-
 hw/unicore32/puv3.c                         |   9 +-
 hw/virtio/virtio.c                          |  45 ++---
 hw/xtensa/sim.c                             |   5 +-
 hw/xtensa/xtfpga.c                          |  17 +-
 numa.c                                      |  22 +--
 qemu-img.c                                  |  16 +-
 qemu-io.c                                   |   9 +-
 qemu-nbd.c                                  | 116 +++++-------
 replay/replay-char.c                        |   9 +-
 replay/replay-events.c                      |  12 +-
 replay/replay-internal.c                    |   4 +-
 replay/replay-time.c                        |   5 +-
 replay/replay.c                             |   9 +-
 scripts/coccinelle/error_report_fatal.cocci |  20 ++
 target-arm/machine.c                        |   5 +-
 target-i386/kvm.c                           |  10 +-
 target-ppc/kvm.c                            |   7 +-
 target-s390x/cpu.c                          |   5 +-
 target-s390x/kvm.c                          |   8 +-
 target-s390x/mmu_helper.c                   |   5 +-
 trace/control.c                             |   6 +-
 ui/spice-core.c                             |  43 ++---
 vl.c                                        | 272 +++++++++++-----------------
 xen-hvm.c                                   |   3 +-
 76 files changed, 557 insertions(+), 799 deletions(-)
 create mode 100644 scripts/coccinelle/error_report_fatal.cocci

diff --git a/arch_init.c b/arch_init.c
index fa05973..cc8aa5d 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -220,14 +220,14 @@ void audio_init(void)
         if (c->enabled) {
             if (c->isa) {
                 if (!isa_bus) {
-                    error_report("ISA bus not available for %s", c->name);
-                    exit(1);
+                    error_report_fatal("ISA bus not available for %s",
+                                       c->name);
                 }
                 c->init.init_isa(isa_bus);
             } else {
                 if (!pci_bus) {
-                    error_report("PCI bus not available for %s", c->name);
-                    exit(1);
+                    error_report_fatal("PCI bus not available for %s",
+                                       c->name);
                 }
                 c->init.init_pci(pci_bus);
             }
diff --git a/bootdevice.c b/bootdevice.c
index 33e3029..69c46bc 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -172,8 +172,8 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
 
     QTAILQ_FOREACH(i, &fw_boot_order, link) {
         if (i->bootindex == bootindex) {
-            error_report("Two devices with same boot index %d", bootindex);
-            exit(1);
+            error_report_fatal("Two devices with same boot index %d",
+                               bootindex);
         } else if (i->bootindex < bootindex) {
             continue;
         }
diff --git a/cpus.c b/cpus.c
index 84c3520..f0d61c8 100644
--- a/cpus.c
+++ b/cpus.c
@@ -975,8 +975,7 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
 static void qemu_kvm_destroy_vcpu(CPUState *cpu)
 {
     if (kvm_destroy_vcpu(cpu) < 0) {
-        error_report("kvm_destroy_vcpu failed");
-        exit(EXIT_FAILURE);
+        error_report_fatal("kvm_destroy_vcpu failed");
     }
 }
 
diff --git a/device_tree.c b/device_tree.c
index 6e06320..3799952 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -60,14 +60,15 @@ void *create_device_tree(int *sizep)
     }
     ret = fdt_open_into(fdt, fdt, *sizep);
     if (ret) {
-        error_report("Unable to copy device tree in memory");
-        exit(1);
+        error_report_fatal("Unable to copy device tree in memory");
     }
 
     return fdt;
 fail:
-    error_report("%s Couldn't create dt: %s", __func__, fdt_strerror(ret));
-    exit(1);
+    error_report_fatal("%s Couldn't create dt: %s", __func__,
+                       fdt_strerror(ret));
+    /* Never reach here. */
+    return NULL;
 }
 
 void *load_device_tree(const char *filename_path, int *sizep)
@@ -140,14 +141,14 @@ static void read_fstree(void *fdt, const char *dirname)
     const char *parent_node;
 
     if (strstr(dirname, root_dir) != dirname) {
-        error_setg(&error_fatal, "%s: %s must be searched within %s",
-                   __func__, dirname, root_dir);
+        error_report_fatal("%s: %s must be searched within %s", __func__,
+                           dirname, root_dir);
     }
     parent_node = &dirname[strlen(SYSFS_DT_BASEDIR)];
 
     d = opendir(dirname);
     if (!d) {
-        error_setg(&error_fatal, "%s cannot open %s", __func__, dirname);
+        error_report_fatal("%s cannot open %s", __func__, dirname);
     }
 
     while ((de = readdir(d)) != NULL) {
@@ -161,7 +162,7 @@ static void read_fstree(void *fdt, const char *dirname)
         tmpnam = g_strdup_printf("%s/%s", dirname, de->d_name);
 
         if (lstat(tmpnam, &st) < 0) {
-            error_setg(&error_fatal, "%s cannot lstat %s", __func__, tmpnam);
+            error_report_fatal("%s cannot lstat %s", __func__, tmpnam);
         }
 
         if (S_ISREG(st.st_mode)) {
@@ -169,8 +170,8 @@ static void read_fstree(void *fdt, const char *dirname)
             gsize len;
 
             if (!g_file_get_contents(tmpnam, &val, &len, NULL)) {
-                error_setg(&error_fatal, "%s not able to extract info from %s",
-                           __func__, tmpnam);
+                error_report_fatal("%s not able to extract info from %s",
+                                   __func__, tmpnam);
             }
 
             if (strlen(parent_node) > 0) {
@@ -205,9 +206,8 @@ void *load_device_tree_from_sysfs(void)
     host_fdt = create_device_tree(&host_fdt_size);
     read_fstree(host_fdt, SYSFS_DT_BASEDIR);
     if (fdt_check_header(host_fdt)) {
-        error_setg(&error_fatal,
-                   "%s host device tree extracted into memory is invalid",
-                   __func__);
+        error_report_fatal("%s host device tree extracted into "
+                           "memory is invalid", __func__);
     }
     return host_fdt;
 }
@@ -220,9 +220,8 @@ static int findnode_nofail(void *fdt, const char *node_path)
 
     offset = fdt_path_offset(fdt, node_path);
     if (offset < 0) {
-        error_report("%s Couldn't find node %s: %s", __func__, node_path,
-                     fdt_strerror(offset));
-        exit(1);
+        error_report_fatal("%s Couldn't find node %s: %s", __func__,
+                           node_path, fdt_strerror(offset));
     }
 
     return offset;
@@ -289,9 +288,8 @@ int qemu_fdt_setprop(void *fdt, const char *node_path,
 
     r = fdt_setprop(fdt, findnode_nofail(fdt, node_path), property, val, size);
     if (r < 0) {
-        error_report("%s: Couldn't set %s/%s: %s", __func__, node_path,
-                     property, fdt_strerror(r));
-        exit(1);
+        error_report_fatal("%s: Couldn't set %s/%s: %s", __func__, node_path,
+                           property, fdt_strerror(r));
     }
 
     return r;
@@ -304,9 +302,8 @@ int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
 
     r = fdt_setprop_cell(fdt, findnode_nofail(fdt, node_path), property, val);
     if (r < 0) {
-        error_report("%s: Couldn't set %s/%s = %#08x: %s", __func__,
-                     node_path, property, val, fdt_strerror(r));
-        exit(1);
+        error_report_fatal("%s: Couldn't set %s/%s = %#08x: %s", __func__,
+                           node_path, property, val, fdt_strerror(r));
     }
 
     return r;
@@ -326,9 +323,8 @@ int qemu_fdt_setprop_string(void *fdt, const char *node_path,
 
     r = fdt_setprop_string(fdt, findnode_nofail(fdt, node_path), property, string);
     if (r < 0) {
-        error_report("%s: Couldn't set %s/%s = %s: %s", __func__,
-                     node_path, property, string, fdt_strerror(r));
-        exit(1);
+        error_report_fatal("%s: Couldn't set %s/%s = %s: %s", __func__,
+                           node_path, property, string, fdt_strerror(r));
     }
 
     return r;
@@ -378,9 +374,8 @@ uint32_t qemu_fdt_get_phandle(void *fdt, const char *path)
 
     r = fdt_get_phandle(fdt, findnode_nofail(fdt, path));
     if (r == 0) {
-        error_report("%s: Couldn't get phandle for %s: %s", __func__,
-                     path, fdt_strerror(r));
-        exit(1);
+        error_report_fatal("%s: Couldn't get phandle for %s: %s", __func__,
+                           path, fdt_strerror(r));
     }
 
     return r;
@@ -423,9 +418,8 @@ int qemu_fdt_nop_node(void *fdt, const char *node_path)
 
     r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path));
     if (r < 0) {
-        error_report("%s: Couldn't nop node %s: %s", __func__, node_path,
-                     fdt_strerror(r));
-        exit(1);
+        error_report_fatal("%s: Couldn't nop node %s: %s", __func__,
+                           node_path, fdt_strerror(r));
     }
 
     return r;
@@ -452,9 +446,8 @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
 
     retval = fdt_add_subnode(fdt, parent, basename);
     if (retval < 0) {
-        error_report("FDT: Failed to create subnode %s: %s", name,
-                     fdt_strerror(retval));
-        exit(1);
+        error_report_fatal("FDT: Failed to create subnode %s: %s", name,
+                           fdt_strerror(retval));
     }
 
     g_free(dupname);
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index dfe293d..0da3fbb 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -3512,8 +3512,7 @@ static void __attribute__((__constructor__)) v9fs_set_fd_limit(void)
 {
     struct rlimit rlim;
     if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
-        error_report("Failed to get the resource limit");
-        exit(1);
+        error_report_fatal("Failed to get the resource limit");
     }
     open_fd_hw = rlim.rlim_cur - MIN(400, rlim.rlim_cur/3);
     open_fd_rc = rlim.rlim_cur/2;
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index f1267b5..b75464d 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -109,15 +109,13 @@ static void clipper_init(MachineState *machine)
     palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
                                 bios_name ? bios_name : "palcode-clipper");
     if (palcode_filename == NULL) {
-        error_report("no palcode provided");
-        exit(1);
+        error_report_fatal("no palcode provided");
     }
     size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,
                     NULL, &palcode_entry, &palcode_low, &palcode_high,
                     0, EM_ALPHA, 0, 0);
     if (size < 0) {
-        error_report("could not load palcode '%s'", palcode_filename);
-        exit(1);
+        error_report_fatal("could not load palcode '%s'", palcode_filename);
     }
     g_free(palcode_filename);
 
@@ -136,8 +134,7 @@ static void clipper_init(MachineState *machine)
                         NULL, &kernel_entry, &kernel_low, &kernel_high,
                         0, EM_ALPHA, 0, 0);
         if (size < 0) {
-            error_report("could not load kernel '%s'", kernel_filename);
-            exit(1);
+            error_report_fatal("could not load kernel '%s'", kernel_filename);
         }
 
         cpus[0]->env.trap_arg1 = kernel_entry;
@@ -153,9 +150,8 @@ static void clipper_init(MachineState *machine)
 
             initrd_size = get_image_size(initrd_filename);
             if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             initrd_filename);
-                exit(1);
+                error_report_fatal("could not load initial ram disk '%s'",
+                                   initrd_filename);
             }
 
             /* Put the initrd image as high in memory as possible.  */
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 49d3078..97d566d 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -220,8 +220,7 @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
             lowaddr = 0;
         }
         if (image_size < 0) {
-            error_report("Could not load kernel '%s'", kernel_filename);
-            exit(1);
+            error_report_fatal("Could not load kernel '%s'", kernel_filename);
         }
     }
 
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 520c8e9..85580bc 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -106,14 +106,12 @@ static void digic_load_rom(DigicBoardState *s, hwaddr addr,
         char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
 
         if (!fn) {
-            error_report("Couldn't find rom image '%s'.", filename);
-            exit(1);
+            error_report_fatal("Couldn't find rom image '%s'.", filename);
         }
 
         rom_size = load_image_targphys(fn, addr, max_size);
         if (rom_size < 0 || rom_size > max_size) {
-            error_report("Couldn't load rom image '%s'.", filename);
-            exit(1);
+            error_report_fatal("Couldn't load rom image '%s'.", filename);
         }
         g_free(fn);
     }
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index 6a1bf26..f46f609 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -36,9 +36,8 @@ static void fsl_imx6_init(Object *obj)
     int i;
 
     if (smp_cpus > FSL_IMX6_NUM_CPUS) {
-        error_report("%s: Only %d CPUs are supported (%d requested)",
-                     TYPE_FSL_IMX6, FSL_IMX6_NUM_CPUS, smp_cpus);
-        exit(1);
+        error_report_fatal("%s: Only %d CPUs are supported (%d requested)",
+                           TYPE_FSL_IMX6, FSL_IMX6_NUM_CPUS, smp_cpus);
     }
 
     for (i = 0; i < smp_cpus; i++) {
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 80e5fd4..478eb3c 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -283,13 +283,11 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
         sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (sysboot_filename != NULL) {
             if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) {
-                error_report("Unable to load %s", bios_name);
-                exit(1);
+                error_report_fatal("Unable to load %s", bios_name);
             }
             g_free(sysboot_filename);
         } else {
-            error_report("Unable to find %s", bios_name);
-            exit(1);
+            error_report_fatal("Unable to find %s", bios_name);
         }
     }
 
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 2b295f1..f772505 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -98,8 +98,8 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
         r = load_image_targphys(machine->firmware, FIRMWARE_ADDR,
                                 ram_size - FIRMWARE_ADDR);
         if (r < 0) {
-            error_report("Failed to load firmware from %s", machine->firmware);
-            exit(1);
+            error_report_fatal("Failed to load firmware from %s",
+                               machine->firmware);
         }
 
         binfo.entry = FIRMWARE_ADDR;
@@ -146,8 +146,7 @@ static void raspi2_init(MachineState *machine)
     blk = di ? blk_by_legacy_dinfo(di) : NULL;
     bus = qdev_get_child_bus(DEVICE(&s->soc), "sd-bus");
     if (bus == NULL) {
-        error_report("No SD bus found in SOC object");
-        exit(1);
+        error_report_fatal("No SD bus found in SOC object");
     }
     carddev = qdev_create(bus, TYPE_SD_CARD);
     qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
index 4e7ac8c..124bbbe 100644
--- a/hw/arm/sabrelite.c
+++ b/hw/arm/sabrelite.c
@@ -50,9 +50,9 @@ static void sabrelite_init(MachineState *machine)
 
     /* Check the amount of memory is compatible with the SOC */
     if (machine->ram_size > FSL_IMX6_MMDC_SIZE) {
-        error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
-                     machine->ram_size, FSL_IMX6_MMDC_SIZE);
-        exit(1);
+        error_report_fatal("RAM size " RAM_ADDR_FMT
+                           " above max supported (%08x)",
+                           machine->ram_size, FSL_IMX6_MMDC_SIZE);
     }
 
     object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX6);
@@ -61,8 +61,7 @@ static void sabrelite_init(MachineState *machine)
 
     object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
     if (err != NULL) {
-        error_report("%s", error_get_pretty(err));
-        exit(1);
+        error_report_fatal("%s", error_get_pretty(err));
     }
 
     memory_region_allocate_system_memory(&s->ram, NULL, "sabrelite.ram",
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index f1b2c6c..c9adb67 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1589,15 +1589,13 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
     }
 
     if (strncmp(rev, "sa1110", 6)) {
-        error_report("Machine requires a SA1110 processor.");
-        exit(1);
+        error_report_fatal("Machine requires a SA1110 processor.");
     }
 
     s->cpu = cpu_arm_init(rev);
 
     if (!s->cpu) {
-        error_report("Unable to find CPU definition");
-        exit(1);
+        error_report_fatal("Unable to find CPU definition");
     }
 
     memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 5debb33..c0ab68e 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -146,9 +146,8 @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
 
     node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
     if (node_offset <= 0) {
-        error_setg(&error_fatal,
-                   "not able to locate clock handle %d in host device tree",
-                   host_phandle);
+        error_report_fatal("not able to locate clock handle %d"
+                           " in host device tree", host_phandle);
     }
     node_path = g_malloc(path_len);
     while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
@@ -157,16 +156,15 @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
         node_path = g_realloc(node_path, path_len);
     }
     if (ret < 0) {
-        error_setg(&error_fatal,
-                   "not able to retrieve node path for clock handle %d",
-                   host_phandle);
+        error_report_fatal("not able to retrieve node path for clock handle %d",
+                           host_phandle);
     }
 
     r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
                          &error_fatal);
     if (strcmp(r, "fixed-clock")) {
-        error_setg(&error_fatal,
-                   "clock handle %d is not a fixed clock", host_phandle);
+        error_report_fatal("clock handle %d is not a fixed clock",
+                           host_phandle);
     }
 
     nodename = strrchr(node_path, '/');
@@ -309,34 +307,34 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
 
     dt_name = sysfs_to_dt_name(vbasedev->name);
     if (!dt_name) {
-        error_setg(&error_fatal, "%s incorrect sysfs device name %s",
-                    __func__, vbasedev->name);
+        error_report_fatal("%s incorrect sysfs device name %s", __func__,
+                           vbasedev->name);
     }
     node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
                                    &error_fatal);
     if (!node_path || !node_path[0]) {
-        error_setg(&error_fatal, "%s unable to retrieve node path for %s/%s",
-                   __func__, dt_name, vdev->compat);
+        error_report_fatal("%s unable to retrieve node path for %s/%s",
+                           __func__, dt_name, vdev->compat);
     }
 
     if (node_path[1]) {
-        error_setg(&error_fatal, "%s more than one node matching %s/%s!",
-                   __func__, dt_name, vdev->compat);
+        error_report_fatal("%s more than one node matching %s/%s!", __func__,
+                           dt_name, vdev->compat);
     }
 
     g_free(dt_name);
 
     if (vbasedev->num_regions != 5) {
-        error_setg(&error_fatal, "%s Does the host dt node combine XGBE/PHY?",
-                   __func__);
+        error_report_fatal("%s Does the host dt node combine XGBE/PHY?",
+                           __func__);
     }
 
     /* generate nodes for DMA_CLK and PTP_CLK */
     r = qemu_fdt_getprop(host_fdt, node_path[0], "clocks",
                          &prop_len, &error_fatal);
     if (prop_len != 8) {
-        error_setg(&error_fatal, "%s clocks property should contain 2 handles",
-                   __func__);
+        error_report_fatal("%s clocks property should contain 2 handles",
+                           __func__);
     }
     host_clock_phandles = (uint32_t *)r;
     guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt);
@@ -448,9 +446,10 @@ static int add_fdt_node(SysBusDevice *sbdev, void *opaque)
             return 0;
         }
     }
-    error_report("Device %s can not be dynamically instantiated",
-                     qdev_fw_name(DEVICE(sbdev)));
-    exit(1);
+    error_report_fatal("Device %s can not be dynamically instantiated",
+                       qdev_fw_name(DEVICE(sbdev)));
+    /* Should never reach here */
+    return -1;
 }
 
 /**
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 58760f4..4c84c96 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -568,22 +568,20 @@ static void vexpress_common_init(MachineState *machine)
         int image_size;
 
         if (drive_get(IF_PFLASH, 0, 0)) {
-            error_report("The contents of the first flash device may be "
-                         "specified with -bios or with -drive if=pflash... "
-                         "but you cannot use both options at once");
-            exit(1);
+            error_report_fatal("The contents of the first flash device "
+                               "may be specified with -bios or with -drive "
+                               "if=pflash... but you cannot use both "
+                               "options at once");
         }
         fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (!fn) {
-            error_report("Could not find ROM image '%s'", bios_name);
-            exit(1);
+            error_report_fatal("Could not find ROM image '%s'", bios_name);
         }
         image_size = load_image_targphys(fn, map[VE_NORFLASH0],
                                          VEXPRESS_FLASH_SIZE);
         g_free(fn);
         if (image_size < 0) {
-            error_report("Could not load ROM image '%s'", bios_name);
-            exit(1);
+            error_report_fatal("Could not load ROM image '%s'", bios_name);
         }
     }
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a193b5a..c8af99e 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -240,8 +240,7 @@ static void create_fdt(VirtBoardInfo *vbi)
     void *fdt = create_device_tree(&vbi->fdt_size);
 
     if (!fdt) {
-        error_report("create_device_tree() failed");
-        exit(1);
+        error_report_fatal("create_device_tree() failed");
     }
 
     vbi->fdt = fdt;
@@ -814,21 +813,19 @@ static void create_one_flash(const char *name, hwaddr flashbase,
         int image_size;
 
         if (drive_get(IF_PFLASH, 0, 0)) {
-            error_report("The contents of the first flash device may be "
-                         "specified with -bios or with -drive if=pflash... "
-                         "but you cannot use both options at once");
-            exit(1);
+            error_report_fatal("The contents of the first flash device "
+                               "may be specified with -bios or with -drive "
+                               "if=pflash... but you cannot use both "
+                               "options at once");
         }
         fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, file);
         if (!fn) {
-            error_report("Could not find ROM image '%s'", file);
-            exit(1);
+            error_report_fatal("Could not find ROM image '%s'", file);
         }
         image_size = load_image_mr(fn, sysbus_mmio_get_region(sbd, 0));
         g_free(fn);
         if (image_size < 0) {
-            error_report("Could not load ROM image '%s'", file);
-            exit(1);
+            error_report_fatal("Could not load ROM image '%s'", file);
         }
     }
 }
@@ -1195,14 +1192,13 @@ static void machvirt_init(MachineState *machine)
      */
     if (!gic_version) {
         if (!kvm_enabled()) {
-            error_report("gic-version=host requires KVM");
-            exit(1);
+            error_report_fatal("gic-version=host requires KVM");
         }
 
         gic_version = kvm_arm_vgic_probe();
         if (!gic_version) {
-            error_report("Unable to determine GIC version supported by host");
-            exit(1);
+            error_report_fatal("Unable to determine GIC version "
+                               "supported by host");
         }
     }
 
@@ -1212,8 +1208,7 @@ static void machvirt_init(MachineState *machine)
     vbi = find_machine_info(cpustr[0]);
 
     if (!vbi) {
-        error_report("mach-virt: CPU %s not supported", cpustr[0]);
-        exit(1);
+        error_report_fatal("mach-virt: CPU %s not supported", cpustr[0]);
     }
 
     /* If we have an EL3 boot ROM then the assumption is that it will
@@ -1237,23 +1232,22 @@ static void machvirt_init(MachineState *machine)
     }
 
     if (max_cpus > virt_max_cpus) {
-        error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
-                     "supported by machine 'mach-virt' (%d)",
-                     max_cpus, virt_max_cpus);
-        exit(1);
+        error_report_fatal("Number of SMP CPUs requested (%d) exceeds max CPUs "
+                           "supported by machine 'mach-virt' (%d)",
+                           max_cpus, virt_max_cpus);
     }
 
     vbi->smp_cpus = smp_cpus;
 
     if (machine->ram_size > vbi->memmap[VIRT_MEM].size) {
-        error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
-        exit(1);
+        error_report_fatal("mach-virt: cannot model more than %dGB RAM",
+                           RAMLIMIT_GB);
     }
 
     if (vms->secure) {
         if (kvm_enabled()) {
-            error_report("mach-virt: KVM does not support Security extensions");
-            exit(1);
+            error_report_fatal("mach-virt: KVM does not support "
+                               "Security extensions");
         }
 
         /* The Secure view of the world is the same as the NonSecure,
@@ -1271,8 +1265,7 @@ static void machvirt_init(MachineState *machine)
 
     oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
     if (!oc) {
-        error_report("Unable to find CPU definition");
-        exit(1);
+        error_report_fatal("Unable to find CPU definition");
     }
     typename = object_class_get_name(oc);
 
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 4ec590a..7de4001 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -40,10 +40,9 @@ static void xlnx_ep108_init(MachineState *machine)
 
     /* Create the memory region to pass to the SoC */
     if (ram_size > XLNX_ZYNQMP_MAX_RAM_SIZE) {
-        error_report("ERROR: RAM size 0x%" PRIx64 " above max supported of "
-                     "0x%llx", ram_size,
-                     XLNX_ZYNQMP_MAX_RAM_SIZE);
-        exit(1);
+        error_report_fatal("ERROR: RAM size 0x%" PRIx64
+                           " above max supported of 0x%llx",
+                           ram_size, XLNX_ZYNQMP_MAX_RAM_SIZE);
     }
 
     if (ram_size < 0x08000000) {
@@ -75,8 +74,7 @@ static void xlnx_ep108_init(MachineState *machine)
         bus = qdev_get_child_bus(DEVICE(&s->soc), bus_name);
         g_free(bus_name);
         if (!bus) {
-            error_report("No SD bus found for SD card %d", i);
-            exit(1);
+            error_report_fatal("No SD bus found for SD card %d", i);
         }
         carddev = qdev_create(bus, TYPE_SD_CARD);
         qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
index 1d9f7ee..a82ad3f 100644
--- a/hw/block/tc58128.c
+++ b/hw/block/tc58128.c
@@ -40,8 +40,7 @@ static void init_dev(tc58128_dev * dev, const char *filename)
 	ret = load_image(filename, dev->flash_contents + 528 * 32);
 	if (ret < 0) {
             if (!qtest_enabled()) {
-                error_report("Could not load flash image %s", filename);
-                exit(1);
+                error_report_fatal("Could not load flash image %s", filename);
             }
 	} else {
 	    /* Build first block with number of blocks */
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 331d766..1f51fb8 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -477,21 +477,18 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
     unsigned out_num = req->elem.out_num;
 
     if (req->elem.out_num < 1 || req->elem.in_num < 1) {
-        error_report("virtio-blk missing headers");
-        exit(1);
+        error_report_fatal("virtio-blk missing headers");
     }
 
     if (unlikely(iov_to_buf(iov, out_num, 0, &req->out,
                             sizeof(req->out)) != sizeof(req->out))) {
-        error_report("virtio-blk request outhdr too short");
-        exit(1);
+        error_report_fatal("virtio-blk request outhdr too short");
     }
 
     iov_discard_front(&iov, &out_num, sizeof(req->out));
 
     if (in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) {
-        error_report("virtio-blk request inhdr too short");
-        exit(1);
+        error_report_fatal("virtio-blk request inhdr too short");
     }
 
     /* We always touch the last byte, so just see how big in_iov is.  */
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
index 885ecc0..eb12599 100644
--- a/hw/char/exynos4210_uart.c
+++ b/hw/char/exynos4210_uart.c
@@ -597,17 +597,16 @@ DeviceState *exynos4210_uart_create(hwaddr addr,
 
     if (!chr) {
         if (channel >= MAX_SERIAL_PORTS) {
-            error_report("Only %d serial ports are supported by QEMU",
-                         MAX_SERIAL_PORTS);
-            exit(1);
+            error_report_fatal("Only %d serial ports are supported by QEMU",
+                               MAX_SERIAL_PORTS);
         }
         chr = serial_hds[channel];
         if (!chr) {
             snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, channel);
             chr = qemu_chr_new(label, "null", NULL);
             if (!(chr)) {
-                error_report("Can't assign serial port to UART%d", channel);
-                exit(1);
+                error_report_fatal("Can't assign serial port to UART%d",
+                                   channel);
             }
         }
     }
diff --git a/hw/core/machine.c b/hw/core/machine.c
index e5a456f..f2720e8 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -334,9 +334,10 @@ static bool machine_get_enforce_config_section(Object *obj, Error **errp)
 
 static int error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
 {
-    error_report("Option '-device %s' cannot be handled by this machine",
-                 object_class_get_name(object_get_class(OBJECT(sbdev))));
-    exit(1);
+    error_report_fatal("Option '-device %s' cannot be handled by this machine",
+                       object_class_get_name(object_get_class(OBJECT(sbdev))));
+    /* Never reach here. */
+    return -1;
 }
 
 static void machine_init_notify(Notifier *notifier, void *data)
diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
index 36f84ab..8daea32 100644
--- a/hw/core/platform-bus.c
+++ b/hw/core/platform-bus.c
@@ -121,8 +121,7 @@ static void platform_bus_map_irq(PlatformBusDevice *pbus, SysBusDevice *sbdev,
 
     irqn = find_first_zero_bit(pbus->used_irqs, max_irqs);
     if (irqn >= max_irqs) {
-        error_report("Platform Bus: Can not fit IRQ line");
-        exit(1);
+        error_report_fatal("Platform Bus: Can not fit IRQ line");
     }
 
     set_bit(irqn, pbus->used_irqs);
@@ -155,9 +154,8 @@ static void platform_bus_map_mmio(PlatformBusDevice *pbus, SysBusDevice *sbdev,
     }
 
     if (!found_region) {
-        error_report("Platform Bus: Can not fit MMIO region of size %"PRIx64,
-                     size);
-        exit(1);
+        error_report_fatal("Platform Bus: Can not fit MMIO region of size %"
+                           PRIx64, size);
     }
 
     /* Map the device's region into our Platform Bus MMIO space */
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 28c31a2..8c5193c 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -2471,9 +2471,8 @@ static void vtd_realize(DeviceState *dev, Error **errp)
     /* Currently Intel IOMMU IR only support "kernel-irqchip={off|split}" */
     if (x86_iommu->intr_supported && kvm_irqchip_in_kernel() &&
         !kvm_irqchip_is_split()) {
-        error_report("Intel Interrupt Remapping cannot work with "
-                     "kernel-irqchip=on, please use 'split|off'.");
-        exit(1);
+        error_report_fatal("Intel Interrupt Remapping cannot work with "
+                           "kernel-irqchip=on, please use 'split|off'.");
     }
 }
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 022dd1b..b000fcd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1168,14 +1168,13 @@ void pc_cpus_init(PCMachineState *pcms)
 
     model_pieces = g_strsplit(machine->cpu_model, ",", 2);
     if (!model_pieces[0]) {
-        error_report("Invalid/empty CPU model name");
-        exit(1);
+        error_report_fatal("Invalid/empty CPU model name");
     }
 
     oc = cpu_class_by_name(TYPE_X86_CPU, model_pieces[0]);
     if (oc == NULL) {
-        error_report("Unable to find CPU definition: %s", model_pieces[0]);
-        exit(1);
+        error_report_fatal("Unable to find CPU definition: %s",
+                           model_pieces[0]);
     }
     typename = object_class_get_name(oc);
     cc = CPU_CLASS(oc);
@@ -1191,9 +1190,8 @@ void pc_cpus_init(PCMachineState *pcms)
      */
     pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
     if (pcms->apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) {
-        error_report("max_cpus is too large. APIC ID of last CPU is %u",
-                     pcms->apic_id_limit - 1);
-        exit(1);
+        error_report_fatal("max_cpus is too large. APIC ID of last CPU is %u",
+                           pcms->apic_id_limit - 1);
     }
 
     pcms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
@@ -1392,9 +1390,8 @@ void pc_memory_init(PCMachineState *pcms,
          (machine->maxram_size > machine->ram_size))) {
         MachineClass *mc = MACHINE_GET_CLASS(machine);
 
-        error_report("\"-memory 'slots|maxmem'\" is not supported by: %s",
-                     mc->name);
-        exit(EXIT_FAILURE);
+        error_report_fatal("\"-memory 'slots|maxmem'\" is not supported by: %s",
+                           mc->name);
     }
 
     /* initialize hotplug memory address space */
@@ -1404,16 +1401,14 @@ void pc_memory_init(PCMachineState *pcms,
             machine->maxram_size - machine->ram_size;
 
         if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
-            error_report("unsupported amount of memory slots: %"PRIu64,
-                         machine->ram_slots);
-            exit(EXIT_FAILURE);
+            error_report_fatal("unsupported amount of memory slots: %" PRIu64,
+                               machine->ram_slots);
         }
 
         if (QEMU_ALIGN_UP(machine->maxram_size,
                           TARGET_PAGE_SIZE) != machine->maxram_size) {
-            error_report("maximum memory size must by aligned to multiple of "
-                         "%d bytes", TARGET_PAGE_SIZE);
-            exit(EXIT_FAILURE);
+            error_report_fatal("maximum memory size must by aligned to "
+                               "multiple of %d bytes", TARGET_PAGE_SIZE);
         }
 
         pcms->hotplug_memory.base =
@@ -1426,9 +1421,8 @@ void pc_memory_init(PCMachineState *pcms,
 
         if ((pcms->hotplug_memory.base + hotplug_mem_size) <
             hotplug_mem_size) {
-            error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
-                         machine->maxram_size);
-            exit(EXIT_FAILURE);
+            error_report_fatal("unsupported amount of maximum memory: "
+                               RAM_ADDR_FMT, machine->maxram_size);
         }
 
         memory_region_init(&pcms->hotplug_memory.mr, OBJECT(pcms),
@@ -2092,8 +2086,8 @@ bool pc_machine_is_smm_enabled(PCMachineState *pcms)
     }
 
     if (pcms->smm == ON_OFF_AUTO_ON) {
-        error_report("System Management Mode not supported by this hypervisor.");
-        exit(1);
+        error_report_fatal("System Management Mode not supported "
+                           "by this hypervisor.");
     }
     return false;
 }
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a07dc81..3c9c2e0 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -404,8 +404,7 @@ static void pc_xen_hvm_init(MachineState *machine)
     PCIBus *bus;
 
     if (!xen_enabled()) {
-        error_report("xenfv machine requires the xen accelerator");
-        exit(1);
+        error_report_fatal("xenfv machine requires the xen accelerator");
     }
 
     pc_xen_hvm_init_pci(machine);
diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
index ce26b2a..a880dcb 100644
--- a/hw/i386/x86-iommu.c
+++ b/hw/i386/x86-iommu.c
@@ -58,9 +58,8 @@ static void x86_iommu_set_default(X86IOMMUState *x86_iommu)
     assert(x86_iommu);
 
     if (x86_iommu_default) {
-        error_report("QEMU does not support multiple vIOMMUs "
-                     "for x86 yet.");
-        exit(1);
+        error_report_fatal("QEMU does not support multiple vIOMMUs "
+                           "for x86 yet.");
     }
 
     x86_iommu_default = x86_iommu;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 45b6df1..2d1e48f 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2851,9 +2851,8 @@ void ide_drive_get(DriveInfo **hd, int n)
      */
 
     if (highest_bus > n_buses) {
-        error_report("Too many IDE buses defined (%d > %d)",
-                     highest_bus, n_buses);
-        exit(1);
+        error_report_fatal("Too many IDE buses defined (%d > %d)",
+                           highest_bus, n_buses);
     }
 
     for (i = 0; i < n; i++) {
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 31791b0..2441b02 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -400,9 +400,8 @@ static void ioapic_realize(DeviceState *dev, Error **errp)
     IOAPICCommonState *s = IOAPIC_COMMON(dev);
 
     if (s->version != 0x11 && s->version != 0x20) {
-        error_report("IOAPIC only supports version 0x11 or 0x20 "
-                     "(default: 0x11).");
-        exit(1);
+        error_report_fatal("IOAPIC only supports version 0x11 or 0x20 "
+                           "(default: 0x11).");
     }
 
     memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s,
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index edbd62f..99b7318 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -65,9 +65,9 @@ static void icp_get_kvm_state(ICPState *ss)
 
     ret = kvm_vcpu_ioctl(ss->cs, KVM_GET_ONE_REG, &reg);
     if (ret != 0) {
-        error_report("Unable to retrieve KVM interrupt controller state"
-                " for CPU %ld: %s", kvm_arch_vcpu_id(ss->cs), strerror(errno));
-        exit(1);
+        error_report_fatal("Unable to retrieve KVM interrupt controller state"
+                           " for CPU %ld: %s", kvm_arch_vcpu_id(ss->cs),
+                           strerror(errno));
     }
 
     ss->xirr = state >> KVM_REG_PPC_ICP_XISR_SHIFT;
@@ -162,9 +162,9 @@ static void ics_get_kvm_state(ICSState *ics)
 
         ret = ioctl(xicskvm->kernel_xics_fd, KVM_GET_DEVICE_ATTR, &attr);
         if (ret != 0) {
-            error_report("Unable to retrieve KVM interrupt controller state"
-                    " for IRQ %d: %s", i + ics->offset, strerror(errno));
-            exit(1);
+            error_report_fatal("Unable to retrieve KVM interrupt "
+                               "controller state for IRQ %d: %s",
+                               i + ics->offset, strerror(errno));
         }
 
         irq->server = state & KVM_XICS_DESTINATION_MASK;
@@ -354,9 +354,8 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
                                   xicskvm->kernel_xics_fd,
                                   kvm_arch_vcpu_id(cs));
         if (ret < 0) {
-            error_report("Unable to connect CPU%ld to kernel XICS: %s",
-                    kvm_arch_vcpu_id(cs), strerror(errno));
-            exit(1);
+            error_report_fatal("Unable to connect CPU%ld to kernel XICS: %s",
+                               kvm_arch_vcpu_id(cs), strerror(errno));
         }
         ss->cap_irq_xics_enabled = true;
     }
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index 142bab9..4531df1 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -44,8 +44,7 @@ static void an5206_init(MachineState *machine)
     }
     cpu = cpu_m68k_init(cpu_model);
     if (!cpu) {
-        error_report("Unable to find m68k CPU definition");
-        exit(1);
+        error_report_fatal("Unable to find m68k CPU definition");
     }
     env = &cpu->env;
 
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 9eebb1a..c1b3a40 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -190,9 +190,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
                                                   ram_size - initrd_offset);
             }
             if (initrd_size < 0) {
-                error_report("qemu: could not load initrd '%s'",
-                             initrd_filename);
-                exit(EXIT_FAILURE);
+                error_report_fatal("qemu: could not load initrd '%s'",
+                                   initrd_filename);
             }
             boot_info.initrd_end = boot_info.initrd_start + initrd_size;
             high = ROUND_UP(high + initrd_size, 4);
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 889cdc7..58e88fe 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -328,8 +328,7 @@ static void mips_fulong2e_init(MachineState *machine)
 
         if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
             !kernel_filename && !qtest_enabled()) {
-            error_report("Could not load MIPS bios '%s'", bios_name);
-            exit(1);
+            error_report_fatal("Could not load MIPS bios '%s'", bios_name);
         }
     }
 
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 73f6c9f..8e105c4 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -196,8 +196,7 @@ static void mips_jazz_init(MachineState *machine,
         bios_size = -1;
     }
     if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
-        error_report("Could not load MIPS bios '%s'", bios_name);
-        exit(1);
+        error_report_fatal("Could not load MIPS bios '%s'", bios_name);
     }
 
     /* Init CPU internal devices */
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index e90857e..dc2d69f 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -809,17 +809,16 @@ static int64_t load_kernel (void)
     /* Sanity check where the kernel has been linked */
     if (kvm_enabled()) {
         if (kernel_entry & 0x80000000ll) {
-            error_report("KVM guest kernels must be linked in useg. "
-                         "Did you forget to enable CONFIG_KVM_GUEST?");
-            exit(1);
+            error_report_fatal("KVM guest kernels must be linked in useg. "
+                               "Did you forget to enable CONFIG_KVM_GUEST?");
         }
 
         xlate_to_kseg0 = cpu_mips_kvm_um_phys_to_kseg0;
     } else {
         if (!(kernel_entry & 0x80000000ll)) {
-            error_report("KVM guest kernels aren't supported with TCG. "
-                         "Did you unintentionally enable CONFIG_KVM_GUEST?");
-            exit(1);
+            error_report_fatal("KVM guest kernels aren't supported with TCG. "
+                               "Did you unintentionally enable "
+                               "CONFIG_KVM_GUEST?");
         }
 
         xlate_to_kseg0 = cpu_mips_phys_to_kseg0;
@@ -949,8 +948,7 @@ static void create_cps(MaltaState *s, const char *cpu_model,
     object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err);
     object_property_set_bool(OBJECT(s->cps), true, "realized", &err);
     if (err != NULL) {
-        error_report("%s", error_get_pretty(err));
-        exit(1);
+        error_report_fatal("%s", error_get_pretty(err));
     }
 
     sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);
@@ -1119,9 +1117,9 @@ void mips_malta_init(MachineState *machine)
     } else {
         /* The flash region isn't executable from a KVM guest */
         if (kvm_enabled()) {
-            error_report("KVM enabled but no -kernel argument was specified. "
-                         "Booting from flash is not supported with KVM.");
-            exit(1);
+            error_report_fatal("KVM enabled but no -kernel argument was "
+                               "specified. Booting from flash is not "
+                               "supported with KVM.");
         }
         /* Load firmware from flash. */
         if (!dinfo) {
@@ -1139,9 +1137,9 @@ void mips_malta_init(MachineState *machine)
             }
             if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
                 !kernel_filename && !qtest_enabled()) {
-                error_report("Could not load MIPS bios '%s', and no "
-                             "-kernel argument was specified", bios_name);
-                exit(1);
+                error_report_fatal("Could not load MIPS bios '%s', and no "
+                                   "-kernel argument was specified",
+                                   bios_name);
             }
         }
         /* In little endian mode the 32bit words in the bios are swapped,
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 1b91195..e14b671 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -199,9 +199,9 @@ mips_mipssim_init(MachineState *machine)
     if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
         !kernel_filename && !qtest_enabled()) {
         /* Bail out if we have neither a kernel image nor boot vector code. */
-        error_report("Could not load MIPS bios '%s', and no "
-                     "-kernel argument was specified", bios_name);
-        exit(1);
+        error_report_fatal("Could not load MIPS bios '%s', and no "
+                           "-kernel argument was specified",
+                           bios_name);
     } else {
         /* We have a boot vector start address. */
         env->active_tc.PC = (target_long)(int32_t)0xbfc00000;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 01f1351..4ea3b6c 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -892,8 +892,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
         }
         if (iov_size(elem->in_sg, elem->in_num) < sizeof(status) ||
             iov_size(elem->out_sg, elem->out_num) < sizeof(ctrl)) {
-            error_report("virtio-net ctrl missing headers");
-            exit(1);
+            error_report_fatal("virtio-net ctrl missing headers");
         }
 
         iov_cnt = elem->out_num;
@@ -1124,19 +1123,18 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
         if (!elem) {
             if (i == 0)
                 return -1;
-            error_report("virtio-net unexpected empty queue: "
-                         "i %zd mergeable %d offset %zd, size %zd, "
-                         "guest hdr len %zd, host hdr len %zd "
-                         "guest features 0x%" PRIx64,
-                         i, n->mergeable_rx_bufs, offset, size,
-                         n->guest_hdr_len, n->host_hdr_len,
-                         vdev->guest_features);
-            exit(1);
+            error_report_fatal("virtio-net unexpected empty queue: "
+                               "i %zd mergeable %d offset %zd, size %zd, "
+                               "guest hdr len %zd, host hdr len %zd "
+                               "guest features 0x%" PRIx64,
+                               i, n->mergeable_rx_bufs, offset, size,
+                               n->guest_hdr_len, n->host_hdr_len,
+                               vdev->guest_features);
         }
 
         if (elem->in_num < 1) {
-            error_report("virtio-net receive queue contains no in buffers");
-            exit(1);
+            error_report_fatal("virtio-net receive queue contains "
+                               "no in buffers");
         }
 
         sg = elem->in_sg;
@@ -1238,15 +1236,13 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
         out_num = elem->out_num;
         out_sg = elem->out_sg;
         if (out_num < 1) {
-            error_report("virtio-net header not in first element");
-            exit(1);
+            error_report_fatal("virtio-net header not in first element");
         }
 
         if (n->has_vnet_hdr) {
             if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) <
                 n->guest_hdr_len) {
-                error_report("virtio-net header incorrect");
-                exit(1);
+                error_report_fatal("virtio-net header incorrect");
             }
             if (n->needs_vnet_hdr_swap) {
                 virtio_net_hdr_swap(vdev, (void *) &mhdr);
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 6a68e59..5dca59e 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -805,9 +805,8 @@ void fw_cfg_add_file_callback(FWCfgState *s,  const char *filename,
     for (i = 0; i <= count; i++) {
         if (i != index &&
             strcmp(s->files->f[index].name, s->files->f[i].name) == 0) {
-            error_report("duplicate fw_cfg file name: %s",
-                         s->files->f[index].name);
-            exit(1);
+            error_report_fatal("duplicate fw_cfg file name: %s",
+                               s->files->f[index].name);
         }
     }
 
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 24fae16..0642def 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1797,9 +1797,8 @@ PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus,
 
     bus = pci_get_bus_devfn(&devfn, rootbus, devaddr);
     if (!bus) {
-        error_report("Invalid PCI device address %s for device %s",
-                     devaddr, pci_nic_names[i]);
-        exit(1);
+        error_report_fatal("Invalid PCI device address %s for device %s",
+                           devaddr, pci_nic_names[i]);
     }
 
     pci_dev = pci_create(bus, devfn, pci_nic_names[i]);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 0cd534d..e7bae45 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -207,9 +207,8 @@ static int sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque)
     }
 
     if (!matched) {
-        error_report("Device %s is not supported by this machine yet.",
-                     qdev_fw_name(DEVICE(sbdev)));
-        exit(1);
+        error_report_fatal("Device %s is not supported by this machine yet.",
+                           qdev_fw_name(DEVICE(sbdev)));
     }
 
     return 0;
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 7d25106..0a2486b 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -230,8 +230,7 @@ static void ppc_core99_init(MachineState *machine)
         bios_size = -1;
     }
     if (bios_size < 0 || bios_size > BIOS_SIZE) {
-        error_report("could not load PowerPC bios '%s'", bios_name);
-        exit(1);
+        error_report_fatal("could not load PowerPC bios '%s'", bios_name);
     }
 
     if (linux_boot) {
@@ -257,8 +256,7 @@ static void ppc_core99_init(MachineState *machine)
                                               kernel_base,
                                               ram_size - kernel_base);
         if (kernel_size < 0) {
-            error_report("could not load kernel '%s'", kernel_filename);
-            exit(1);
+            error_report_fatal("could not load kernel '%s'", kernel_filename);
         }
         /* load initrd */
         if (initrd_filename) {
@@ -266,9 +264,8 @@ static void ppc_core99_init(MachineState *machine)
             initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                               ram_size - initrd_base);
             if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             initrd_filename);
-                exit(1);
+                error_report_fatal("could not load initial ram disk '%s'",
+                                   initrd_filename);
             }
             cmdline_base = round_page(initrd_base + initrd_size);
         } else {
@@ -349,8 +346,7 @@ static void ppc_core99_init(MachineState *machine)
             break;
 #endif /* defined(TARGET_PPC64) */
         default:
-            error_report("Bus model not supported on mac99 machine");
-            exit(1);
+            error_report_fatal("Bus model not supported on mac99 machine");
         }
     }
 
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 4479487..72cb9df 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -157,8 +157,7 @@ static void ppc_heathrow_init(MachineState *machine)
         bios_size = -1;
     }
     if (bios_size < 0 || bios_size > BIOS_SIZE) {
-        error_report("could not load PowerPC bios '%s'", bios_name);
-        exit(1);
+        error_report_fatal("could not load PowerPC bios '%s'", bios_name);
     }
 
     if (linux_boot) {
@@ -183,8 +182,7 @@ static void ppc_heathrow_init(MachineState *machine)
                                               kernel_base,
                                               ram_size - kernel_base);
         if (kernel_size < 0) {
-            error_report("could not load kernel '%s'", kernel_filename);
-            exit(1);
+            error_report_fatal("could not load kernel '%s'", kernel_filename);
         }
         /* load initrd */
         if (initrd_filename) {
@@ -192,9 +190,8 @@ static void ppc_heathrow_init(MachineState *machine)
             initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                               ram_size - initrd_base);
             if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             initrd_filename);
-                exit(1);
+                error_report_fatal("could not load initial ram disk '%s'",
+                                   initrd_filename);
             }
             cmdline_base = round_page(initrd_base + initrd_size);
         } else {
@@ -250,8 +247,8 @@ static void ppc_heathrow_init(MachineState *machine)
                 ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT];
             break;
         default:
-            error_report("Bus model not supported on OldWorld Mac machine");
-            exit(1);
+            error_report_fatal("Bus model not supported on "
+                               "OldWorld Mac machine");
         }
     }
 
@@ -264,8 +261,7 @@ static void ppc_heathrow_init(MachineState *machine)
 
     /* init basic PC hardware */
     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
-        error_report("Only 6xx bus is supported on heathrow machine");
-        exit(1);
+        error_report_fatal("Only 6xx bus is supported on heathrow machine");
     }
     pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs);
     pci_bus = pci_grackle_init(0xfec00000, pic,
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 27b8289..12ce036 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -42,8 +42,8 @@ static void mpc8544ds_init(MachineState *machine)
     };
 
     if (machine->ram_size > 0xc0000000) {
-        error_report("The MPC8544DS board only supports up to 3GB of RAM");
-        exit(1);
+        error_report_fatal("The MPC8544DS board only supports up to "
+                           "3GB of RAM");
     }
 
     ppce500_init(machine, &params);
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 4b2f07a..afba5ff 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -265,14 +265,13 @@ static void ref405ep_init(MachineState *machine)
             bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
             if (bios_size < 0 || bios_size > BIOS_SIZE) {
-                error_report("Could not load PowerPC BIOS '%s'", bios_name);
-                exit(1);
+                error_report_fatal("Could not load PowerPC BIOS '%s'",
+                                   bios_name);
             }
             bios_size = (bios_size + 0xfff) & ~0xfff;
             memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
         } else if (!qtest_enabled() || kernel_filename != NULL) {
-            error_report("Could not load PowerPC BIOS '%s'", bios_name);
-            exit(1);
+            error_report_fatal("Could not load PowerPC BIOS '%s'", bios_name);
         } else {
             /* Avoid an uninitialized variable warning */
             bios_size = -1;
@@ -563,14 +562,13 @@ static void taihu_405ep_init(MachineState *machine)
             bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
             if (bios_size < 0 || bios_size > BIOS_SIZE) {
-                error_report("Could not load PowerPC BIOS '%s'", bios_name);
-                exit(1);
+                error_report_fatal("Could not load PowerPC BIOS '%s'",
+                                   bios_name);
             }
             bios_size = (bios_size + 0xfff) & ~0xfff;
             memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
         } else if (!qtest_enabled()) {
-            error_report("Could not load PowerPC BIOS '%s'", bios_name);
-            exit(1);
+            error_report_fatal("Could not load PowerPC BIOS '%s'", bios_name);
         }
         memory_region_set_readonly(bios, true);
     }
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 054af1e..1d29f87 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -536,8 +536,7 @@ static void ppc_prep_init(MachineState *machine)
         kernel_size = load_image_targphys(kernel_filename, kernel_base,
                                           ram_size - kernel_base);
         if (kernel_size < 0) {
-            error_report("could not load kernel '%s'", kernel_filename);
-            exit(1);
+            error_report_fatal("could not load kernel '%s'", kernel_filename);
         }
         /* load initrd */
         if (initrd_filename) {
@@ -545,9 +544,8 @@ static void ppc_prep_init(MachineState *machine)
             initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                               ram_size - initrd_base);
             if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             initrd_filename);
-                exit(1);
+                error_report_fatal("could not load initial ram disk '%s'",
+                                   initrd_filename);
             }
         } else {
             initrd_base = 0;
@@ -574,8 +572,7 @@ static void ppc_prep_init(MachineState *machine)
     }
 
     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
-        error_report("Only 6xx bus is supported on PREP machine");
-        exit(1);
+        error_report_fatal("Only 6xx bus is supported on PREP machine");
     }
 
     dev = qdev_create(NULL, "raven-pcihost");
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 30d6800..0ce4011 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -975,8 +975,7 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
     QLIST_FOREACH(phb, &spapr->phbs, list) {
         ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt);
         if (ret < 0) {
-            error_report("couldn't setup PCI devices in fdt");
-            exit(1);
+            error_report_fatal("couldn't setup PCI devices in fdt");
         }
     }
 
@@ -1026,17 +1025,15 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr,
         ret = spapr_drc_populate_dt(fdt, offset, NULL,
                                     SPAPR_DR_CONNECTOR_TYPE_CPU);
         if (ret < 0) {
-            error_report("Couldn't set up CPU DR device tree properties");
-            exit(1);
+            error_report_fatal("Couldn't set up CPU DR device tree properties");
         }
     }
 
     _FDT((fdt_pack(fdt)));
 
     if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {
-        error_report("FDT too big ! 0x%x bytes (max is 0x%x)",
-                     fdt_totalsize(fdt), FDT_MAX_SIZE);
-        exit(1);
+        error_report_fatal("FDT too big ! 0x%x bytes (max is 0x%x)",
+                           fdt_totalsize(fdt), FDT_MAX_SIZE);
     }
 
     qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
@@ -1167,9 +1164,8 @@ static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
     }
 
     if (!matched) {
-        error_report("Device %s is not supported by this machine yet.",
-                     qdev_fw_name(DEVICE(sbdev)));
-        exit(1);
+        error_report_fatal("Device %s is not supported by this machine yet.",
+                           qdev_fw_name(DEVICE(sbdev)));
     }
 
     return 0;
@@ -1737,14 +1733,12 @@ static void ppc_spapr_init(MachineState *machine)
 
     if (mc->query_hotpluggable_cpus) {
         if (smp_cpus % smp_threads) {
-            error_report("smp_cpus (%u) must be multiple of threads (%u)",
-                         smp_cpus, smp_threads);
-            exit(1);
+            error_report_fatal("smp_cpus (%u) must be multiple of threads (%u)",
+                               smp_cpus, smp_threads);
         }
         if (max_cpus % smp_threads) {
-            error_report("max_cpus (%u) must be multiple of threads (%u)",
-                         max_cpus, smp_threads);
-            exit(1);
+            error_report_fatal("max_cpus (%u) must be multiple of threads (%u)",
+                               max_cpus, smp_threads);
         }
     }
 
@@ -1758,8 +1752,7 @@ static void ppc_spapr_init(MachineState *machine)
     rma_alloc_size = kvmppc_alloc_rma(&rma);
 
     if (rma_alloc_size == -1) {
-        error_report("Unable to create RMA");
-        exit(1);
+        error_report_fatal("Unable to create RMA");
     }
 
     if (rma_alloc_size && (rma_alloc_size < node0_size)) {
@@ -1790,9 +1783,8 @@ static void ppc_spapr_init(MachineState *machine)
     }
 
     if (spapr->rma_size > node0_size) {
-        error_report("Numa node 0 has to span the RMA (%#08"HWADDR_PRIx")",
-                     spapr->rma_size);
-        exit(1);
+        error_report_fatal("Numa node 0 has to span the RMA (%#08"
+                           HWADDR_PRIx ")", spapr->rma_size);
     }
 
     /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */
@@ -1818,8 +1810,7 @@ static void ppc_spapr_init(MachineState *machine)
         char *type = spapr_get_cpu_core_type(machine->cpu_model);
 
         if (type == NULL) {
-            error_report("Unable to find sPAPR CPU Core definition");
-            exit(1);
+            error_report_fatal("Unable to find sPAPR CPU Core definition");
         }
 
         spapr->cores = g_new0(Object *, spapr_max_cores);
@@ -1846,8 +1837,7 @@ static void ppc_spapr_init(MachineState *machine)
         for (i = 0; i < smp_cpus; i++) {
             PowerPCCPU *cpu = cpu_ppc_init(machine->cpu_model);
             if (cpu == NULL) {
-                error_report("Unable to find PowerPC CPU definition");
-                exit(1);
+                error_report_fatal("Unable to find PowerPC CPU definition");
             }
             spapr_cpu_init(spapr, cpu, &error_fatal);
        }
@@ -1887,10 +1877,9 @@ static void ppc_spapr_init(MachineState *machine)
             max_memslots = SPAPR_MAX_RAM_SLOTS;
         }
         if (machine->ram_slots > max_memslots) {
-            error_report("Specified number of memory slots %"
-                         PRIu64" exceeds max supported %d",
-                         machine->ram_slots, max_memslots);
-            exit(1);
+            error_report_fatal("Specified number of memory slots %"
+                               PRIu64 " exceeds max supported %d",
+                               machine->ram_slots, max_memslots);
         }
 
         spapr->hotplug_memory.base = ROUND_UP(machine->ram_size,
@@ -1907,23 +1896,19 @@ static void ppc_spapr_init(MachineState *machine)
 
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");
     if (!filename) {
-        error_report("Could not find LPAR rtas '%s'", "spapr-rtas.bin");
-        exit(1);
+        error_report_fatal("Could not find LPAR rtas '%s'", "spapr-rtas.bin");
     }
     spapr->rtas_size = get_image_size(filename);
     if (spapr->rtas_size < 0) {
-        error_report("Could not get size of LPAR rtas '%s'", filename);
-        exit(1);
+        error_report_fatal("Could not get size of LPAR rtas '%s'", filename);
     }
     spapr->rtas_blob = g_malloc(spapr->rtas_size);
     if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
-        error_report("Could not load LPAR rtas '%s'", filename);
-        exit(1);
+        error_report_fatal("Could not load LPAR rtas '%s'", filename);
     }
     if (spapr->rtas_size > RTAS_MAX_SIZE) {
-        error_report("RTAS too big ! 0x%zx bytes (max is 0x%x)",
-                     (size_t)spapr->rtas_size, RTAS_MAX_SIZE);
-        exit(1);
+        error_report_fatal("RTAS too big ! 0x%zx bytes (max is 0x%x)",
+                           (size_t)spapr->rtas_size, RTAS_MAX_SIZE);
     }
     g_free(filename);
 
@@ -1990,10 +1975,9 @@ static void ppc_spapr_init(MachineState *machine)
     }
 
     if (spapr->rma_size < (MIN_RMA_SLOF << 20)) {
-        error_report(
-            "pSeries SLOF firmware requires >= %ldM guest RMA (Real Mode Area memory)",
-            MIN_RMA_SLOF);
-        exit(1);
+        error_report_fatal("pSeries SLOF firmware requires >= %ldM "
+                           "guest RMA (Real Mode Area memory)",
+                           MIN_RMA_SLOF);
     }
 
     if (kernel_filename) {
@@ -2010,9 +1994,8 @@ static void ppc_spapr_init(MachineState *machine)
             kernel_le = kernel_size > 0;
         }
         if (kernel_size < 0) {
-            error_report("error loading %s: %s",
-                         kernel_filename, load_elf_strerror(kernel_size));
-            exit(1);
+            error_report_fatal("error loading %s: %s", kernel_filename,
+                               load_elf_strerror(kernel_size));
         }
 
         /* load initrd */
@@ -2024,9 +2007,8 @@ static void ppc_spapr_init(MachineState *machine)
             initrd_size = load_image_targphys(initrd_filename, initrd_base,
                                               load_limit - initrd_base);
             if (initrd_size < 0) {
-                error_report("could not load initial ram disk '%s'",
-                             initrd_filename);
-                exit(1);
+                error_report_fatal("could not load initial ram disk '%s'",
+                                   initrd_filename);
             }
         } else {
             initrd_base = 0;
@@ -2039,13 +2021,11 @@ static void ppc_spapr_init(MachineState *machine)
     }
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (!filename) {
-        error_report("Could not find LPAR firmware '%s'", bios_name);
-        exit(1);
+        error_report_fatal("Could not find LPAR firmware '%s'", bios_name);
     }
     fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);
     if (fw_size <= 0) {
-        error_report("Could not load LPAR firmware '%s'", filename);
-        exit(1);
+        error_report_fatal("Could not load LPAR firmware '%s'", filename);
     }
     g_free(filename);
 
@@ -2084,8 +2064,9 @@ static int spapr_kvm_type(const char *vm_type)
         return 2;
     }
 
-    error_report("Unknown kvm-type specified '%s'", vm_type);
-    exit(1);
+    error_report_fatal("Unknown kvm-type specified '%s'", vm_type);
+    /* Should never reach here */
+    return -1;
 }
 
 /*
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index b97d966..803881e 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -282,9 +282,8 @@ static void virtex_init(MachineState *machine)
                                               high, ram_size - high);
 
             if (initrd_size < 0) {
-                error_report("couldn't load ram disk '%s'",
-                             machine->initrd_filename);
-                exit(1);
+                error_report_fatal("couldn't load ram disk '%s'",
+                                   machine->initrd_filename);
             }
             high = ROUND_UP(high + initrd_size, 4);
         }
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 5b26946..78b85be 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -171,8 +171,8 @@ static void vhost_scsi_set_config(VirtIODevice *vdev,
 
     if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size ||
         (uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) {
-        error_report("vhost-scsi does not support changing the sense data and CDB sizes");
-        exit(1);
+        error_report_fatal("vhost-scsi does not support changing "
+                           "the sense data and CDB sizes");
     }
 }
 
@@ -190,11 +190,8 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val)
 
         ret = vhost_scsi_start(s);
         if (ret < 0) {
-            error_report("virtio-scsi: unable to start vhost: %s",
-                         strerror(-ret));
-
-            /* There is no userspace virtio-scsi fallback so exit */
-            exit(1);
+            error_report_fatal("virtio-scsi: unable to start vhost: %s",
+                               strerror(-ret));
         }
     } else {
         vhost_scsi_stop(s);
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ce57ef6..e5e0c0b 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -83,8 +83,7 @@ static void virtio_scsi_complete_req(VirtIOSCSIReq *req)
 
 static void virtio_scsi_bad_req(void)
 {
-    error_report("wrong size for virtio-scsi headers");
-    exit(1);
+    error_report_fatal("wrong size for virtio-scsi headers");
 }
 
 static size_t qemu_sgl_concat(VirtIOSCSIReq *req, struct iovec *iov,
@@ -207,8 +206,7 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
 
     if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,
                               sizeof(VirtIOSCSICmdResp) + vs->sense_size) < 0) {
-        error_report("invalid SCSI request migration data");
-        exit(1);
+        error_report_fatal("invalid SCSI request migration data");
     }
 
     scsi_req_ref(sreq);
@@ -624,8 +622,8 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
 
     if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) >= 65536 ||
         (uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) >= 256) {
-        error_report("bad data written to virtio-scsi configuration space");
-        exit(1);
+        error_report_fatal("bad data written to virtio-scsi "
+                           "configuration space");
     }
 
     vs->sense_size = virtio_ldl_p(vdev, &scsiconf->sense_size);
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index ccc9e75..b6406b8 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -81,8 +81,7 @@ static void shix_init(MachineState *machine)
         bios_name = BIOS_FILENAME;
     ret = load_image_targphys(bios_name, 0, 0x4000);
     if (ret < 0 && !qtest_enabled()) {
-        error_report("Could not load SHIX bios '%s'", bios_name);
-        exit(1);
+        error_report_fatal("Could not load SHIX bios '%s'", bios_name);
     }
 
     /* Register peripherals */
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 74c7102..91da615 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -330,9 +330,8 @@ static void smbios_validate_table(void)
     uint32_t expect_t4_count = smbios_legacy ? smp_cpus : smbios_smp_sockets;
 
     if (smbios_type4_count && smbios_type4_count != expect_t4_count) {
-        error_report("Expected %d SMBIOS Type 4 tables, got %d instead",
-                     expect_t4_count, smbios_type4_count);
-        exit(1);
+        error_report_fatal("Expected %d SMBIOS Type 4 tables, got %d instead",
+                           expect_t4_count, smbios_type4_count);
     }
 }
 
@@ -731,9 +730,8 @@ void smbios_set_defaults(const char *manufacturer, const char *product,
         /* in legacy mode, also complain if fields were given for types > 1 */
         if (find_next_bit(have_fields_bitmap,
                           SMBIOS_MAX_TYPE+1, 2) < SMBIOS_MAX_TYPE+1) {
-            error_report("can't process fields for smbios "
-                         "types > 1 on machine versions < 2.1!");
-            exit(1);
+            error_report_fatal("can't process fields for smbios "
+                               "types > 1 on machine versions < 2.1!");
         }
     } else {
         g_free(smbios_entries);
@@ -897,8 +895,7 @@ void smbios_entry_add(QemuOpts *opts)
 
         size = get_image_size(val);
         if (size == -1 || size < sizeof(struct smbios_structure_header)) {
-            error_report("Cannot read SMBIOS file %s", val);
-            exit(1);
+            error_report_fatal("Cannot read SMBIOS file %s", val);
         }
 
         /*
@@ -911,14 +908,13 @@ void smbios_entry_add(QemuOpts *opts)
                                                     smbios_tables_len);
 
         if (load_image(val, (uint8_t *)header) != size) {
-            error_report("Failed to load SMBIOS file %s", val);
-            exit(1);
+            error_report_fatal("Failed to load SMBIOS file %s", val);
         }
 
         if (test_bit(header->type, have_fields_bitmap)) {
-            error_report("can't load type %d struct, fields already specified!",
-                         header->type);
-            exit(1);
+            error_report_fatal("can't load type %d struct, "
+                               "fields already specified!",
+                               header->type);
         }
         set_bit(header->type, have_binfile_bitmap);
 
@@ -963,13 +959,11 @@ void smbios_entry_add(QemuOpts *opts)
         unsigned long type = strtoul(val, NULL, 0);
 
         if (type > SMBIOS_MAX_TYPE) {
-            error_report("out of range!");
-            exit(1);
+            error_report_fatal("out of range!");
         }
 
         if (test_bit(type, have_binfile_bitmap)) {
-            error_report("can't add fields, binary file already loaded!");
-            exit(1);
+            error_report_fatal("can't add fields, binary file already loaded!");
         }
         set_bit(type, have_fields_bitmap);
 
@@ -984,8 +978,7 @@ void smbios_entry_add(QemuOpts *opts)
             val = qemu_opt_get(opts, "release");
             if (val) {
                 if (sscanf(val, "%hhu.%hhu", &type0.major, &type0.minor) != 2) {
-                    error_report("Invalid release");
-                    exit(1);
+                    error_report_fatal("Invalid release");
                 }
                 type0.have_major_minor = true;
             }
@@ -1002,8 +995,7 @@ void smbios_entry_add(QemuOpts *opts)
             val = qemu_opt_get(opts, "uuid");
             if (val) {
                 if (qemu_uuid_parse(val, qemu_uuid) != 0) {
-                    error_report("Invalid UUID");
-                    exit(1);
+                    error_report_fatal("Invalid UUID");
                 }
                 qemu_uuid_set = true;
             }
@@ -1045,12 +1037,10 @@ void smbios_entry_add(QemuOpts *opts)
             type17.speed = qemu_opt_get_number(opts, "speed", 0);
             return;
         default:
-            error_report("Don't know how to build fields for SMBIOS type %ld",
-                         type);
-            exit(1);
+            error_report_fatal("Don't know how to build fields for "
+                               "SMBIOS type %ld", type);
         }
     }
 
-    error_report("Must specify type= or file=");
-    exit(1);
+    error_report_fatal("Must specify type= or file=");
 }
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 478fda8..91be01f 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -943,22 +943,19 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
                              slavio_irq[16], iommu, &ledma_irq, 1);
 
     if (graphic_depth != 8 && graphic_depth != 24) {
-        error_report("Unsupported depth: %d", graphic_depth);
-        exit (1);
+        error_report_fatal("Unsupported depth: %d", graphic_depth);
     }
     num_vsimms = 0;
     if (num_vsimms == 0) {
         if (vga_interface_type == VGA_CG3) {
             if (graphic_depth != 8) {
-                error_report("Unsupported depth: %d", graphic_depth);
-                exit(1);
+                error_report_fatal("Unsupported depth: %d", graphic_depth);
             }
 
             if (!(graphic_width == 1024 && graphic_height == 768) &&
                 !(graphic_width == 1152 && graphic_height == 900)) {
-                error_report("Unsupported resolution: %d x %d", graphic_width,
-                             graphic_height);
-                exit(1);
+                error_report_fatal("Unsupported resolution: %d x %d",
+                                   graphic_width, graphic_height);
             }
 
             /* sbus irq 5 */
@@ -967,14 +964,12 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
         } else {
             /* If no display specified, default to TCX */
             if (graphic_depth != 8 && graphic_depth != 24) {
-                error_report("Unsupported depth: %d", graphic_depth);
-                exit(1);
+                error_report_fatal("Unsupported depth: %d", graphic_depth);
             }
 
             if (!(graphic_width == 1024 && graphic_height == 768)) {
-                error_report("Unsupported resolution: %d x %d",
-                             graphic_width, graphic_height);
-                exit(1);
+                error_report_fatal("Unsupported resolution: %d x %d",
+                                   graphic_width, graphic_height);
             }
 
             tcx_init(hwdef->tcx_base, slavio_irq[11], 0x00100000,
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index 8d3520f..ef65064 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -50,9 +50,8 @@ static void tricore_load_kernel(CPUTriCoreState *env)
                            NULL, 0,
                            EM_TRICORE, 1, 0);
     if (kernel_size <= 0) {
-        error_report("qemu: no kernel file '%s'",
-                tricoretb_binfo.kernel_filename);
-        exit(1);
+        error_report_fatal("qemu: no kernel file '%s'",
+                           tricoretb_binfo.kernel_filename);
     }
     env->PC = entry;
 
@@ -76,8 +75,7 @@ static void tricore_testboard_init(MachineState *machine, int board_id)
     }
     cpu = cpu_tricore_init(machine->cpu_model);
     if (!cpu) {
-        error_report("Unable to find CPU definition");
-        exit(1);
+        error_report_fatal("Unable to find CPU definition");
     }
     env = &cpu->env;
     memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram", 2*1024*1024,
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 31cd171..3a30db6 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -100,8 +100,7 @@ static void puv3_load_kernel(const char *kernel_filename)
     size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,
             KERNEL_MAX_SIZE);
     if (size < 0) {
-        error_report("Load kernel error: '%s'", kernel_filename);
-        exit(1);
+        error_report_fatal("Load kernel error: '%s'", kernel_filename);
     }
 
     /* cheat curses that we have a graphic console, only under ocd console */
@@ -118,8 +117,7 @@ static void puv3_init(MachineState *machine)
     UniCore32CPU *cpu;
 
     if (initrd_filename) {
-        error_report("Please use kernel built-in initramdisk");
-        exit(1);
+        error_report_fatal("Please use kernel built-in initramdisk");
     }
 
     if (!cpu_model) {
@@ -128,8 +126,7 @@ static void puv3_init(MachineState *machine)
 
     cpu = uc32_cpu_init(cpu_model);
     if (!cpu) {
-        error_report("Unable to find CPU definition");
-        exit(1);
+        error_report_fatal("Unable to find CPU definition");
     }
     env = &cpu->env;
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 74c085c..3128ed4 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -315,9 +315,8 @@ static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx)
 
     /* Check it isn't doing very strange things with descriptor numbers. */
     if (num_heads > vq->vring.num) {
-        error_report("Guest moved used index from %u to %u",
-                     idx, vq->shadow_avail_idx);
-        exit(1);
+        error_report_fatal("Guest moved used index from %u to %u", idx,
+                           vq->shadow_avail_idx);
     }
     /* On success, callers read a descriptor at vq->last_avail_idx.
      * Make sure descriptor read does not bypass avail index read. */
@@ -338,8 +337,7 @@ static unsigned int virtqueue_get_head(VirtQueue *vq, unsigned int idx)
 
     /* If their number is silly, that's a fatal mistake. */
     if (head >= vq->vring.num) {
-        error_report("Guest says index %u is available", head);
-        exit(1);
+        error_report_fatal("Guest says index %u is available", head);
     }
 
     return head;
@@ -361,8 +359,7 @@ static unsigned virtqueue_read_next_desc(VirtIODevice *vdev, VRingDesc *desc,
     smp_wmb();
 
     if (next >= max) {
-        error_report("Desc next is %u", next);
-        exit(1);
+        error_report_fatal("Desc next is %u", next);
     }
 
     vring_desc_read(vdev, desc, desc_pa, next);
@@ -394,14 +391,12 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
 
         if (desc.flags & VRING_DESC_F_INDIRECT) {
             if (desc.len % sizeof(VRingDesc)) {
-                error_report("Invalid size for indirect buffer table");
-                exit(1);
+                error_report_fatal("Invalid size for indirect buffer table");
             }
 
             /* If we've got too many, that implies a descriptor loop. */
             if (num_bufs >= max) {
-                error_report("Looped descriptor");
-                exit(1);
+                error_report_fatal("Looped descriptor");
             }
 
             /* loop over the indirect descriptor table */
@@ -415,8 +410,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
         do {
             /* If we've got too many, that implies a descriptor loop. */
             if (++num_bufs > max) {
-                error_report("Looped descriptor");
-                exit(1);
+                error_report_fatal("Looped descriptor");
             }
 
             if (desc.flags & VRING_DESC_F_WRITE) {
@@ -460,16 +454,15 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
     assert(num_sg <= max_num_sg);
 
     if (!sz) {
-        error_report("virtio: zero sized buffers are not allowed");
-        exit(1);
+        error_report_fatal("virtio: zero sized buffers are not allowed");
     }
 
     while (sz) {
         hwaddr len = sz;
 
         if (num_sg == max_num_sg) {
-            error_report("virtio: too many write descriptors in indirect table");
-            exit(1);
+            error_report_fatal("virtio: too many write descriptors "
+                               "in indirect table");
         }
 
         iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
@@ -506,12 +499,10 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
         len = sg[i].iov_len;
         sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
         if (!sg[i].iov_base) {
-            error_report("virtio: error trying to map MMIO memory");
-            exit(1);
+            error_report_fatal("virtio: error trying to map MMIO memory");
         }
         if (len != sg[i].iov_len) {
-            error_report("virtio: unexpected memory split");
-            exit(1);
+            error_report_fatal("virtio: unexpected memory split");
         }
     }
 }
@@ -569,8 +560,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     max = vq->vring.num;
 
     if (vq->inuse >= vq->vring.num) {
-        error_report("Virtqueue size exceeded");
-        exit(1);
+        error_report_fatal("Virtqueue size exceeded");
     }
 
     i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
@@ -581,8 +571,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
     vring_desc_read(vdev, &desc, desc_pa, i);
     if (desc.flags & VRING_DESC_F_INDIRECT) {
         if (desc.len % sizeof(VRingDesc)) {
-            error_report("Invalid size for indirect buffer table");
-            exit(1);
+            error_report_fatal("Invalid size for indirect buffer table");
         }
 
         /* loop over the indirect descriptor table */
@@ -599,8 +588,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
                                VIRTQUEUE_MAX_SIZE - out_num, true, desc.addr, desc.len);
         } else {
             if (in_num) {
-                error_report("Incorrect order for descriptors");
-                exit(1);
+                error_report_fatal("Incorrect order for descriptors");
             }
             virtqueue_map_desc(&out_num, addr, iov,
                                VIRTQUEUE_MAX_SIZE, false, desc.addr, desc.len);
@@ -608,8 +596,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
 
         /* If we've got too many, that implies a descriptor loop. */
         if ((in_num + out_num) > max) {
-            error_report("Looped descriptor");
-            exit(1);
+            error_report_fatal("Looped descriptor");
         }
     } while ((i = virtqueue_read_next_desc(vdev, &desc, desc_pa, max)) != max);
 
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index 5e94004..48e4d3f 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -68,9 +68,8 @@ static void xtensa_sim_init(MachineState *machine)
     for (n = 0; n < smp_cpus; n++) {
         cpu = cpu_xtensa_init(cpu_model);
         if (cpu == NULL) {
-            error_report("unable to find CPU definition '%s'",
-                         cpu_model);
-            exit(EXIT_FAILURE);
+            error_report_fatal("unable to find CPU definition '%s'",
+                               cpu_model);
         }
         env = &cpu->env;
 
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index ac75949..ba02bde 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -234,9 +234,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
     for (n = 0; n < smp_cpus; n++) {
         cpu = cpu_xtensa_init(cpu_model);
         if (cpu == NULL) {
-            error_report("unable to find CPU definition '%s'",
-                         cpu_model);
-            exit(EXIT_FAILURE);
+            error_report_fatal("unable to find CPU definition '%s'",
+                               cpu_model);
         }
         env = &cpu->env;
 
@@ -323,8 +322,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
             uint32_t dtb_addr = tswap32(cur_lowmem);
 
             if (!fdt) {
-                error_report("could not load DTB '%s'", dtb_filename);
-                exit(EXIT_FAILURE);
+                error_report_fatal("could not load DTB '%s'", dtb_filename);
             }
 
             cpu_physical_memory_write(cur_lowmem, fdt, fdt_size);
@@ -343,8 +341,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
                                                   lowmem_end - cur_lowmem);
             }
             if (initrd_size < 0) {
-                error_report("could not load initrd '%s'", initrd_filename);
-                exit(EXIT_FAILURE);
+                error_report_fatal("could not load initrd '%s'",
+                                   initrd_filename);
             }
             initrd_location.start = tswap32(cur_lowmem);
             initrd_location.end = tswap32(cur_lowmem + initrd_size);
@@ -369,9 +367,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
             if (success > 0 && is_linux) {
                 entry_point = ep;
             } else {
-                error_report("could not load kernel '%s'",
-                             kernel_filename);
-                exit(EXIT_FAILURE);
+                error_report_fatal("could not load kernel '%s'",
+                                   kernel_filename);
             }
         }
         if (entry_point != env->pc) {
diff --git a/numa.c b/numa.c
index 6289f46..6560172 100644
--- a/numa.c
+++ b/numa.c
@@ -274,9 +274,8 @@ static void validate_numa_cpus(void)
                               MAX_CPUMASK_BITS)) {
             bitmap_and(seen_cpus, seen_cpus,
                        numa_info[i].node_cpu, MAX_CPUMASK_BITS);
-            error_report("CPU(s) present in multiple NUMA nodes: %s",
-                         enumerate_cpus(seen_cpus, max_cpus));
-            exit(EXIT_FAILURE);
+            error_report_fatal("CPU(s) present in multiple NUMA nodes: %s",
+                               enumerate_cpus(seen_cpus, max_cpus));
         }
         bitmap_or(seen_cpus, seen_cpus,
                   numa_info[i].node_cpu, MAX_CPUMASK_BITS);
@@ -307,8 +306,7 @@ void parse_numa_opts(MachineClass *mc)
     for (i = max_numa_nodeid - 1; i >= 0; i--) {
         /* Report large node IDs first, to make mistakes easier to spot */
         if (!numa_info[i].present) {
-            error_report("numa: Node ID missing: %d", i);
-            exit(1);
+            error_report_fatal("numa: Node ID missing: %d", i);
         }
     }
 
@@ -349,10 +347,9 @@ void parse_numa_opts(MachineClass *mc)
             numa_total += numa_info[i].node_mem;
         }
         if (numa_total != ram_size) {
-            error_report("total memory for NUMA nodes (0x%" PRIx64 ")"
-                         " should equal RAM size (0x" RAM_ADDR_FMT ")",
-                         numa_total, ram_size);
-            exit(1);
+            error_report_fatal("total memory for NUMA nodes (0x%" PRIx64
+                               ") should equal RAM size (0x" RAM_ADDR_FMT ")",
+                               numa_total, ram_size);
         }
 
         for (i = 0; i < nb_numa_nodes; i++) {
@@ -458,10 +455,9 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
 
         if (memory_region_is_mapped(seg)) {
             char *path = object_get_canonical_path_component(OBJECT(backend));
-            error_report("memory backend %s is used multiple times. Each "
-                         "-numa option must use a different memdev value.",
-                         path);
-            exit(1);
+            error_report_fatal("memory backend %s is used multiple times. "
+                               "Each -numa option must use a different "
+                               "memdev value.", path);
         }
 
         host_memory_backend_set_mapped(backend, true);
diff --git a/qemu-img.c b/qemu-img.c
index f204d041..7bc4637 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2415,8 +2415,8 @@ static void dump_map_entry(OutputFormat output_format, MapEntry *e,
     switch (output_format) {
     case OFORMAT_HUMAN:
         if (e->data && !e->has_offset) {
-            error_report("File contains external, encrypted or compressed clusters.");
-            exit(1);
+            error_report_fatal("File contains external, encrypted "
+                               "or compressed clusters.");
         }
         if (e->data && !e->zero) {
             printf("%#-16"PRIx64"%#-16"PRIx64"%#-16"PRIx64"%s\n",
@@ -3490,8 +3490,7 @@ typedef struct BenchData {
 static void bench_undrained_flush_cb(void *opaque, int ret)
 {
     if (ret < 0) {
-        error_report("Failed flush request: %s", strerror(-ret));
-        exit(EXIT_FAILURE);
+        error_report_fatal("Failed flush request: %s", strerror(-ret));
     }
 }
 
@@ -3501,8 +3500,7 @@ static void bench_cb(void *opaque, int ret)
     BlockAIOCB *acb;
 
     if (ret < 0) {
-        error_report("Failed request: %s", strerror(-ret));
-        exit(EXIT_FAILURE);
+        error_report_fatal("Failed request: %s", strerror(-ret));
     }
 
     if (b->in_flush) {
@@ -3529,8 +3527,7 @@ static void bench_cb(void *opaque, int ret)
 
                 acb = blk_aio_flush(b->blk, cb, b);
                 if (!acb) {
-                    error_report("Failed to issue flush request");
-                    exit(EXIT_FAILURE);
+                    error_report_fatal("Failed to issue flush request");
                 }
             }
             if (b->drain_on_flush) {
@@ -3548,8 +3545,7 @@ static void bench_cb(void *opaque, int ret)
                                  bench_cb, b);
         }
         if (!acb) {
-            error_report("Failed to issue request");
-            exit(EXIT_FAILURE);
+            error_report_fatal("Failed to issue request");
         }
         b->in_flight++;
         b->offset += b->step;
diff --git a/qemu-io.c b/qemu-io.c
index db129ea..1120b31 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -488,8 +488,7 @@ int main(int argc, char **argv)
             break;
         case 'd':
             if (bdrv_parse_discard_flags(optarg, &flags) < 0) {
-                error_report("Invalid discard option: %s", optarg);
-                exit(1);
+                error_report_fatal("Invalid discard option: %s", optarg);
             }
             break;
         case 'f':
@@ -509,8 +508,7 @@ int main(int argc, char **argv)
             break;
         case 't':
             if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
-                error_report("Invalid cache option: %s", optarg);
-                exit(1);
+                error_report_fatal("Invalid cache option: %s", optarg);
             }
             break;
         case 'T':
@@ -546,8 +544,7 @@ int main(int argc, char **argv)
     }
 
     if (format && imageOpts) {
-        error_report("--image-opts and -f are mutually exclusive");
-        exit(1);
+        error_report_fatal("--image-opts and -f are mutually exclusive");
     }
 
     if (qemu_init_main_loop(&local_error)) {
diff --git a/qemu-nbd.c b/qemu-nbd.c
index e3571c2..0e6b52e 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -173,8 +173,7 @@ static int find_partition(BlockBackend *blk, int partition,
 
     ret = blk_pread(blk, 0, data, sizeof(data));
     if (ret < 0) {
-        error_report("error while reading: %s", strerror(-ret));
-        exit(EXIT_FAILURE);
+        error_report_fatal("error while reading: %s", strerror(-ret));
     }
 
     if (data[510] != 0x55 || data[511] != 0xaa) {
@@ -196,8 +195,7 @@ static int find_partition(BlockBackend *blk, int partition,
             ret = blk_pread(blk, mbr[i].start_sector_abs * MBR_SIZE,
                             data1, sizeof(data1));
             if (ret < 0) {
-                error_report("error while reading: %s", strerror(-ret));
-                exit(EXIT_FAILURE);
+                error_report_fatal("error while reading: %s", strerror(-ret));
             }
 
             for (j = 0; j < 4; j++) {
@@ -550,19 +548,16 @@ int main(int argc, char **argv)
             /* fallthrough */
         case QEMU_NBD_OPT_CACHE:
             if (seen_cache) {
-                error_report("-n and --cache can only be specified once");
-                exit(EXIT_FAILURE);
+                error_report_fatal("-n and --cache can only be specified once");
             }
             seen_cache = true;
             if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) == -1) {
-                error_report("Invalid cache mode `%s'", optarg);
-                exit(EXIT_FAILURE);
+                error_report_fatal("Invalid cache mode `%s'", optarg);
             }
             break;
         case QEMU_NBD_OPT_AIO:
             if (seen_aio) {
-                error_report("--aio can only be specified once");
-                exit(EXIT_FAILURE);
+                error_report_fatal("--aio can only be specified once");
             }
             seen_aio = true;
             if (!strcmp(optarg, "native")) {
@@ -570,19 +565,16 @@ int main(int argc, char **argv)
             } else if (!strcmp(optarg, "threads")) {
                 /* this is the default */
             } else {
-               error_report("invalid aio mode `%s'", optarg);
-               exit(EXIT_FAILURE);
+               error_report_fatal("invalid aio mode `%s'", optarg);
             }
             break;
         case QEMU_NBD_OPT_DISCARD:
             if (seen_discard) {
-                error_report("--discard can only be specified once");
-                exit(EXIT_FAILURE);
+                error_report_fatal("--discard can only be specified once");
             }
             seen_discard = true;
             if (bdrv_parse_discard_flags(optarg, &flags) == -1) {
-                error_report("Invalid discard mode `%s'", optarg);
-                exit(EXIT_FAILURE);
+                error_report_fatal("Invalid discard mode `%s'", optarg);
             }
             break;
         case QEMU_NBD_OPT_DETECT_ZEROES:
@@ -599,9 +591,9 @@ int main(int argc, char **argv)
             }
             if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&
                 !(flags & BDRV_O_UNMAP)) {
-                error_report("setting detect-zeroes to unmap is not allowed "
-                             "without setting discard operation to unmap");
-                exit(EXIT_FAILURE);
+                error_report_fatal("setting detect-zeroes to unmap is not "
+                                   "allowed without setting discard "
+                                   "operation to unmap");
             }
             break;
         case 'b':
@@ -613,12 +605,10 @@ int main(int argc, char **argv)
         case 'o':
                 dev_offset = strtoll (optarg, &end, 0);
             if (*end) {
-                error_report("Invalid offset `%s'", optarg);
-                exit(EXIT_FAILURE);
+                error_report_fatal("Invalid offset `%s'", optarg);
             }
             if (dev_offset < 0) {
-                error_report("Offset must be positive `%s'", optarg);
-                exit(EXIT_FAILURE);
+                error_report_fatal("Offset must be positive `%s'", optarg);
             }
             break;
         case 'l':
@@ -626,9 +616,8 @@ int main(int argc, char **argv)
                 sn_opts = qemu_opts_parse_noisily(&internal_snapshot_opts,
                                                   optarg, false);
                 if (!sn_opts) {
-                    error_report("Failed in parsing snapshot param `%s'",
-                                 optarg);
-                    exit(EXIT_FAILURE);
+                    error_report_fatal("Failed in parsing snapshot param `%s'",
+                                       optarg);
                 }
             } else {
                 sn_id_or_name = optarg;
@@ -641,19 +630,16 @@ int main(int argc, char **argv)
         case 'P':
             partition = strtol(optarg, &end, 0);
             if (*end) {
-                error_report("Invalid partition `%s'", optarg);
-                exit(EXIT_FAILURE);
+                error_report_fatal("Invalid partition `%s'", optarg);
             }
             if (partition < 1 || partition > 8) {
-                error_report("Invalid partition %d", partition);
-                exit(EXIT_FAILURE);
+                error_report_fatal("Invalid partition %d", partition);
             }
             break;
         case 'k':
             sockpath = optarg;
             if (sockpath[0] != '/') {
-                error_report("socket path must be absolute");
-                exit(EXIT_FAILURE);
+                error_report_fatal("socket path must be absolute");
             }
             break;
         case 'd':
@@ -665,12 +651,12 @@ int main(int argc, char **argv)
         case 'e':
             shared = strtol(optarg, &end, 0);
             if (*end) {
-                error_report("Invalid shared device number '%s'", optarg);
-                exit(EXIT_FAILURE);
+                error_report_fatal("Invalid shared device number '%s'",
+                                   optarg);
             }
             if (shared < 1) {
-                error_report("Shared device number must be greater than 0");
-                exit(EXIT_FAILURE);
+                error_report_fatal("Shared device number must be "
+                                   "greater than 0");
             }
             break;
         case 'f':
@@ -694,8 +680,8 @@ int main(int argc, char **argv)
             exit(0);
             break;
         case '?':
-            error_report("Try `%s --help' for more information.", argv[0]);
-            exit(EXIT_FAILURE);
+            error_report_fatal("Try `%s --help' for more information.",
+                               argv[0]);
         case QEMU_NBD_OPT_OBJECT: {
             QemuOpts *opts;
             opts = qemu_opts_parse_noisily(&qemu_object_opts,
@@ -737,12 +723,10 @@ int main(int argc, char **argv)
 
     if (tlscredsid) {
         if (sockpath) {
-            error_report("TLS is only supported with IPv4/IPv6");
-            exit(EXIT_FAILURE);
+            error_report_fatal("TLS is only supported with IPv4/IPv6");
         }
         if (device) {
-            error_report("TLS is not supported with a host device");
-            exit(EXIT_FAILURE);
+            error_report_fatal("TLS is not supported with a host device");
         }
         if (!export_name) {
             /* Set the default NBD protocol export name, since
@@ -751,18 +735,16 @@ int main(int argc, char **argv)
         }
         tlscreds = nbd_get_tls_creds(tlscredsid, &local_err);
         if (local_err) {
-            error_report("Failed to get TLS creds %s",
-                         error_get_pretty(local_err));
-            exit(EXIT_FAILURE);
+            error_report_fatal("Failed to get TLS creds %s",
+                               error_get_pretty(local_err));
         }
     }
 
     if (disconnect) {
         int nbdfd = open(argv[optind], O_RDWR);
         if (nbdfd < 0) {
-            error_report("Cannot open %s: %s", argv[optind],
-                         strerror(errno));
-            exit(EXIT_FAILURE);
+            error_report_fatal("Cannot open %s: %s", argv[optind],
+                               strerror(errno));
         }
         nbd_disconnect(nbdfd);
 
@@ -779,9 +761,8 @@ int main(int argc, char **argv)
         int ret;
 
         if (qemu_pipe(stderr_fd) < 0) {
-            error_report("Error setting up communication pipe: %s",
-                         strerror(errno));
-            exit(EXIT_FAILURE);
+            error_report_fatal("Error setting up communication pipe: %s",
+                               strerror(errno));
         }
 
         /* Now daemonize, but keep a communication channel open to
@@ -789,8 +770,7 @@ int main(int argc, char **argv)
          */
         pid = fork();
         if (pid < 0) {
-            error_report("Failed to fork: %s", strerror(errno));
-            exit(EXIT_FAILURE);
+            error_report_fatal("Failed to fork: %s", strerror(errno));
         } else if (pid == 0) {
             close(stderr_fd[0]);
             ret = qemu_daemon(1, 0);
@@ -798,8 +778,7 @@ int main(int argc, char **argv)
             /* Temporarily redirect stderr to the parent's pipe...  */
             dup2(stderr_fd[1], STDERR_FILENO);
             if (ret < 0) {
-                error_report("Failed to daemonize: %s", strerror(errno));
-                exit(EXIT_FAILURE);
+                error_report_fatal("Failed to daemonize: %s", strerror(errno));
             }
 
             /* ... close the descriptor we inherited and go on.  */
@@ -821,9 +800,8 @@ int main(int argc, char **argv)
                 }
             }
             if (ret < 0) {
-                error_report("Cannot read from daemon: %s",
-                             strerror(errno));
-                exit(EXIT_FAILURE);
+                error_report_fatal("Cannot read from daemon: %s",
+                                   strerror(errno));
             }
 
             /* Usually the daemon should not print any message.
@@ -851,8 +829,7 @@ int main(int argc, char **argv)
     if (imageOpts) {
         QemuOpts *opts;
         if (fmt) {
-            error_report("--image-opts and -f are mutually exclusive");
-            exit(EXIT_FAILURE);
+            error_report_fatal("--image-opts and -f are mutually exclusive");
         }
         opts = qemu_opts_parse_noisily(&file_opts, srcpath, true);
         if (!opts) {
@@ -896,17 +873,15 @@ int main(int argc, char **argv)
     bs->detect_zeroes = detect_zeroes;
     fd_size = blk_getlength(blk);
     if (fd_size < 0) {
-        error_report("Failed to determine the image length: %s",
-                     strerror(-fd_size));
-        exit(EXIT_FAILURE);
+        error_report_fatal("Failed to determine the image length: %s",
+                           strerror(-fd_size));
     }
 
     if (partition != -1) {
         ret = find_partition(blk, partition, &dev_offset, &fd_size);
         if (ret < 0) {
-            error_report("Could not find partition %d: %s", partition,
-                         strerror(-ret));
-            exit(EXIT_FAILURE);
+            error_report_fatal("Could not find partition %d: %s", partition,
+                               strerror(-ret));
         }
     }
 
@@ -933,8 +908,8 @@ int main(int argc, char **argv)
 
         ret = pthread_create(&client_thread, NULL, nbd_client_thread, device);
         if (ret != 0) {
-            error_report("Failed to create client thread: %s", strerror(ret));
-            exit(EXIT_FAILURE);
+            error_report_fatal("Failed to create client thread: %s",
+                               strerror(ret));
         }
     } else {
         /* Shut up GCC warnings.  */
@@ -946,9 +921,8 @@ int main(int argc, char **argv)
     /* now when the initialization is (almost) complete, chdir("/")
      * to free any busy filesystems */
     if (chdir("/") < 0) {
-        error_report("Could not chdir to root directory: %s",
-                     strerror(errno));
-        exit(EXIT_FAILURE);
+        error_report_fatal("Could not chdir to root directory: %s",
+                           strerror(errno));
     }
 
     state = RUNNING;
diff --git a/replay/replay-char.c b/replay/replay-char.c
index edf46ab..75624c3 100755
--- a/replay/replay-char.c
+++ b/replay/replay-char.c
@@ -115,8 +115,7 @@ void replay_char_write_event_load(int *res, int *offset)
         replay_mutex_unlock();
     } else {
         replay_mutex_unlock();
-        error_report("Missing character write event in the replay log");
-        exit(1);
+        error_report_fatal("Missing character write event in the replay log");
     }
 }
 
@@ -139,8 +138,10 @@ int replay_char_read_all_load(uint8_t *buf)
         return res;
     } else {
         replay_mutex_unlock();
-        error_report("Missing character read all event in the replay log");
-        exit(1);
+        error_report_fatal("Missing character read all event "
+                           "in the replay log");
+        /* Never reach here. */
+        return -1;
     }
 }
 
diff --git a/replay/replay-events.c b/replay/replay-events.c
index 3807245..281b7db 100644
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -55,9 +55,8 @@ static void replay_run_event(Event *event)
         aio_bh_call(event->opaque);
         break;
     default:
-        error_report("Replay: invalid async event ID (%d) in the queue",
-                    event->event_kind);
-        exit(1);
+        error_report_fatal("Replay: invalid async event ID (%d) in the queue",
+                           event->event_kind);
         break;
     }
 }
@@ -190,8 +189,8 @@ static void replay_save_event(Event *event, int checkpoint)
             replay_put_qword(event->id);
             break;
         default:
-            error_report("Unknown ID %" PRId64 " of replay event", event->id);
-            exit(1);
+            error_report_fatal("Unknown ID %" PRId64 " of replay event",
+                               event->id);
         }
     }
 }
@@ -253,8 +252,7 @@ static Event *replay_read_event(int checkpoint)
         }
         break;
     default:
-        error_report("Unknown ID %d of replay event", read_event_kind);
-        exit(1);
+        error_report_fatal("Unknown ID %d of replay event", read_event_kind);
         break;
     }
 
diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index 5835e8d..3839d51 100644
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -158,8 +158,8 @@ void replay_fetch_data_kind(void)
             replay_check_error();
             replay_has_unread_data = 1;
             if (replay_data_kind >= EVENT_COUNT) {
-                error_report("Replay: unknown event kind %d", replay_data_kind);
-                exit(1);
+                error_report_fatal("Replay: unknown event kind %d",
+                                   replay_data_kind);
             }
         }
     }
diff --git a/replay/replay-time.c b/replay/replay-time.c
index fffe072..e26b9e1 100644
--- a/replay/replay-time.c
+++ b/replay/replay-time.c
@@ -60,6 +60,7 @@ int64_t replay_read_clock(ReplayClockKind kind)
         return ret;
     }
 
-    error_report("REPLAY INTERNAL ERROR %d", __LINE__);
-    exit(1);
+    error_report_fatal("REPLAY INTERNAL ERROR %d", __LINE__);
+    /* Never reach here */
+    return -1;
 }
diff --git a/replay/replay.c b/replay/replay.c
index 167fd29..dc89d24 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -281,14 +281,12 @@ void replay_configure(QemuOpts *opts)
     } else if (!strcmp(rr, "replay")) {
         mode = REPLAY_MODE_PLAY;
     } else {
-        error_report("Invalid icount rr option: %s", rr);
-        exit(1);
+        error_report_fatal("Invalid icount rr option: %s", rr);
     }
 
     fname = qemu_opt_get(opts, "rrfile");
     if (!fname) {
-        error_report("File name not specified for replay");
-        exit(1);
+        error_report_fatal("File name not specified for replay");
     }
 
     replay_enable(fname, mode);
@@ -308,8 +306,7 @@ void replay_start(void)
         exit(1);
     }
     if (!use_icount) {
-        error_report("Please enable icount to use record/replay");
-        exit(1);
+        error_report_fatal("Please enable icount to use record/replay");
     }
 
     /* Timer for snapshotting will be set up here. */
diff --git a/scripts/coccinelle/error_report_fatal.cocci b/scripts/coccinelle/error_report_fatal.cocci
new file mode 100644
index 0000000..f720c65
--- /dev/null
+++ b/scripts/coccinelle/error_report_fatal.cocci
@@ -0,0 +1,20 @@
+@@
+expression list X;
+@@
+
+-error_report(X);
++error_report_fatal(X);
+-exit(
+(
+-1
+|
+-EXIT_FAILURE
+)
+-);
+
+@@
+expression list X;
+@@
+
+-error_setg(&error_fatal, X);
++error_report_fatal(X);
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 7a6ca31..88c3a61 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -338,9 +338,8 @@ const char *gicv3_class_name(void)
 #ifdef TARGET_AARCH64
         return "kvm-arm-gicv3";
 #else
-        error_report("KVM GICv3 acceleration is not supported on this "
-                     "platform");
-        exit(1);
+        error_report_fatal("KVM GICv3 acceleration is not supported on this "
+                           "platform");
 #endif
     } else {
         return "arm-gicv3";
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index d1a25c5..e6ab6d2 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -3244,8 +3244,7 @@ void kvm_arch_init_irq_routing(KVMState *s)
            MSI routes for signaling interrupts to the local apics. */
         for (i = 0; i < IOAPIC_NUM_PINS; i++) {
             if (kvm_irqchip_add_msi_route(s, 0, NULL) < 0) {
-                error_report("Could not enable split IRQ mode.");
-                exit(1);
+                error_report_fatal("Could not enable split IRQ mode.");
             }
         }
     }
@@ -3257,9 +3256,10 @@ int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
     if (machine_kernel_irqchip_split(ms)) {
         ret = kvm_vm_enable_cap(s, KVM_CAP_SPLIT_IRQCHIP, 0, 24);
         if (ret) {
-            error_report("Could not enable split irqchip mode: %s",
-                         strerror(-ret));
-            exit(1);
+            error_report_fatal("Could not enable split irqchip mode: %s",
+                               strerror(-ret));
+            /* Never reach here. */
+            return -1;
         } else {
             DPRINTF("Enabled KVM_CAP_SPLIT_IRQCHIP\n");
             kvm_split_irqchip = true;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index dcb68b9..f08e8c2 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2062,8 +2062,8 @@ void kvmppc_set_papr(PowerPCCPU *cpu)
 
     ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_PAPR, 0);
     if (ret) {
-        error_report("This vCPU type or KVM version does not support PAPR");
-        exit(1);
+        error_report_fatal("This vCPU type or KVM version does "
+                           "not support PAPR");
     }
 
     /* Update the capability flag so we sync the right information
@@ -2083,8 +2083,7 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
 
     ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_EPR, 0, mpic_proxy);
     if (ret && mpic_proxy) {
-        error_report("This KVM version does not support EPR");
-        exit(1);
+        error_report_fatal("This KVM version does not support EPR");
     }
 }
 
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index e43e2d6..7f42731 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -400,9 +400,8 @@ unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
         s390_cpu_unhalt(cpu);
         break;
     default:
-        error_report("Requested CPU state is not a valid S390 CPU state: %u",
-                     cpu_state);
-        exit(1);
+        error_report_fatal("Requested CPU state is not a valid "
+                           "S390 CPU state: %u", cpu_state);
     }
     if (kvm_enabled() && cpu->env.cpu_state != cpu_state) {
         kvm_s390_set_cpu_state(cpu, cpu_state);
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 80ac621..8fad340 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -909,8 +909,7 @@ void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq)
         if (!r) {
             return;
         }
-        error_report("KVM failed to inject interrupt %llx", irq->type);
-        exit(1);
+        error_report_fatal("KVM failed to inject interrupt %llx", irq->type);
     }
 
     inject_vcpu_irq_legacy(cs, irq);
@@ -2181,9 +2180,8 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
         mp_state.mp_state = KVM_MP_STATE_LOAD;
         break;
     default:
-        error_report("Requested CPU state is not a valid S390 CPU state: %u",
-                     cpu_state);
-        exit(1);
+        error_report_fatal("Requested CPU state is not a valid S390 "
+                           "CPU state: %u", cpu_state);
     }
 
     ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MP_STATE, &mp_state);
diff --git a/target-s390x/mmu_helper.c b/target-s390x/mmu_helper.c
index b11a027..15107fa 100644
--- a/target-s390x/mmu_helper.c
+++ b/target-s390x/mmu_helper.c
@@ -413,8 +413,9 @@ static bool lowprot_enabled(const CPUS390XState *env)
         return !(env->cregs[13] & _ASCE_PRIVATE_SPACE);
     default:
         /* We don't support access register mode */
-        error_report("unsupported addressing mode");
-        exit(1);
+        error_report_fatal("unsupported addressing mode");
+        /* Should never reach here */
+        return false;
     }
 }
 
diff --git a/trace/control.c b/trace/control.c
index d173c09..e4c49d8 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -192,8 +192,7 @@ static void trace_init_events(const char *fname)
     loc_set_file(fname, 0);
     fp = fopen(fname, "r");
     if (!fp) {
-        error_report("%s", strerror(errno));
-        exit(1);
+        error_report_fatal("%s", strerror(errno));
     }
     while (fgets(line_buf, sizeof(line_buf), fp)) {
         loc_set_file(fname, ++line_idx);
@@ -208,8 +207,7 @@ static void trace_init_events(const char *fname)
     }
     if (fclose(fp) != 0) {
         loc_set_file(fname, 0);
-        error_report("%s", strerror(errno));
-        exit(1);
+        error_report_fatal("%s", strerror(errno));
     }
     loc_pop(&loc);
 }
diff --git a/ui/spice-core.c b/ui/spice-core.c
index da05054..f28e19e 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -332,8 +332,9 @@ static int parse_name(const char *string, const char *optname,
     if (value != -1) {
         return value;
     }
-    error_report("spice: invalid %s: %s", optname, string);
-    exit(1);
+    error_report_fatal("spice: invalid %s: %s", optname, string);
+    /* Never reach here. */
+    return -1;
 }
 
 static const char *stream_video_names[] = {
@@ -603,9 +604,8 @@ static int add_channel(void *opaque, const char *name, const char *value,
     if (strcmp(name, "tls-channel") == 0) {
         int *tls_port = opaque;
         if (!*tls_port) {
-            error_report("spice: tried to setup tls-channel"
-                         " without specifying a TLS port");
-            exit(1);
+            error_report_fatal("spice: tried to setup tls-channel"
+                               " without specifying a TLS port");
         }
         security = SPICE_CHANNEL_SECURITY_SSL;
     }
@@ -621,8 +621,8 @@ static int add_channel(void *opaque, const char *name, const char *value,
         rc = spice_server_set_channel_security(spice_server, value, security);
     }
     if (rc != 0) {
-        error_report("spice: failed to set channel security for %s", value);
-        exit(1);
+        error_report_fatal("spice: failed to set channel security for %s",
+                           value);
     }
     return 0;
 }
@@ -660,12 +660,10 @@ void qemu_spice_init(void)
     port = qemu_opt_get_number(opts, "port", 0);
     tls_port = qemu_opt_get_number(opts, "tls-port", 0);
     if (port < 0 || port > 65535) {
-        error_report("spice port is out of range");
-        exit(1);
+        error_report_fatal("spice port is out of range");
     }
     if (tls_port < 0 || tls_port > 65535) {
-        error_report("spice tls-port is out of range");
-        exit(1);
+        error_report_fatal("spice tls-port is out of range");
     }
     password = qemu_opt_get(opts, "password");
 
@@ -735,8 +733,7 @@ void qemu_spice_init(void)
     }
     if (qemu_opt_get_bool(opts, "sasl", 0)) {
         if (spice_server_set_sasl(spice_server, 1) == -1) {
-            error_report("spice: failed to enable sasl");
-            exit(1);
+            error_report_fatal("spice: failed to enable sasl");
         }
         auth = "sasl";
     }
@@ -753,9 +750,8 @@ void qemu_spice_init(void)
 #if SPICE_SERVER_VERSION >= 0x000c04
         spice_server_set_agent_file_xfer(spice_server, false);
 #else
-        error_report("this qemu build does not support the "
-                     "\"disable-agent-file-xfer\" option");
-        exit(1);
+        error_report_fatal("this qemu build does not support the "
+                           "\"disable-agent-file-xfer\" option");
 #endif
     }
 
@@ -802,8 +798,7 @@ void qemu_spice_init(void)
     spice_server_set_seamless_migration(spice_server, seamless_migration);
     spice_server_set_sasl_appname(spice_server, "qemu");
     if (spice_server_init(spice_server, &core_interface) != 0) {
-        error_report("failed to initialize spice server");
-        exit(1);
+        error_report_fatal("failed to initialize spice server");
     };
     using_spice = 1;
 
@@ -829,13 +824,12 @@ void qemu_spice_init(void)
 #ifdef HAVE_SPICE_GL
     if (qemu_opt_get_bool(opts, "gl", 0)) {
         if ((port != 0) || (tls_port != 0)) {
-            error_report("SPICE GL support is local-only for now and "
-                         "incompatible with -spice port/tls-port");
-            exit(1);
+            error_report_fatal("SPICE GL support is local-only for now and "
+                               "incompatible with -spice port/tls-port");
         }
         if (egl_rendernode_init() != 0) {
-            error_report("Failed to initialize EGL render node for SPICE GL");
-            exit(1);
+            error_report_fatal("Failed to initialize EGL render "
+                               "node for SPICE GL");
         }
         display_opengl = 1;
     }
@@ -846,8 +840,7 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
 {
     if (!spice_server) {
         if (QTAILQ_FIRST(&qemu_spice_opts.head) != NULL) {
-            error_report("Oops: spice configured but not active");
-            exit(1);
+            error_report_fatal("Oops: spice configured but not active");
         }
         /*
          * Create a spice server instance.
diff --git a/vl.c b/vl.c
index b3c80d5..6939b99 100644
--- a/vl.c
+++ b/vl.c
@@ -866,8 +866,7 @@ static void configure_rtc(QemuOpts *opts)
         } else if (!strcmp(value, "vm")) {
             rtc_clock = QEMU_CLOCK_VIRTUAL;
         } else {
-            error_report("invalid option value '%s'", value);
-            exit(1);
+            error_report_fatal("invalid option value '%s'", value);
         }
     }
     value = qemu_opt_get(opts, "driftfix");
@@ -883,8 +882,7 @@ static void configure_rtc(QemuOpts *opts)
         } else if (!strcmp(value, "none")) {
             /* discard is default */
         } else {
-            error_report("invalid option value '%s'", value);
-            exit(1);
+            error_report_fatal("invalid option value '%s'", value);
         }
     }
 }
@@ -1219,31 +1217,27 @@ static void smp_parse(QemuOpts *opts)
             threads = cpus / (cores * sockets);
             threads = threads > 0 ? threads : 1;
         } else if (sockets * cores * threads < cpus) {
-            error_report("cpu topology: "
-                         "sockets (%u) * cores (%u) * threads (%u) < "
-                         "smp_cpus (%u)",
-                         sockets, cores, threads, cpus);
-            exit(1);
+            error_report_fatal("cpu topology: "
+                               "sockets (%u) * cores (%u) * threads (%u) < "
+                               "smp_cpus (%u)",
+                               sockets, cores, threads, cpus);
         }
 
         max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
 
         if (max_cpus > MAX_CPUMASK_BITS) {
-            error_report("unsupported number of maxcpus");
-            exit(1);
+            error_report_fatal("unsupported number of maxcpus");
         }
 
         if (max_cpus < cpus) {
-            error_report("maxcpus must be equal to or greater than smp");
-            exit(1);
+            error_report_fatal("maxcpus must be equal to or greater than smp");
         }
 
         if (sockets * cores * threads > max_cpus) {
-            error_report("cpu topology: "
-                         "sockets (%u) * cores (%u) * threads (%u) > "
-                         "maxcpus (%u)",
-                         sockets, cores, threads, max_cpus);
-            exit(1);
+            error_report_fatal("cpu topology: "
+                               "sockets (%u) * cores (%u) * threads (%u) > "
+                               "maxcpus (%u)",
+                               sockets, cores, threads, max_cpus);
         }
 
         smp_cpus = cpus;
@@ -1262,8 +1256,7 @@ static void realtime_init(void)
 {
     if (enable_mlock) {
         if (os_mlock() < 0) {
-            error_report("locking memory failed");
-            exit(1);
+            error_report_fatal("locking memory failed");
         }
     }
 }
@@ -2026,8 +2019,7 @@ static void select_vgahw(const char *p)
         VGAInterfaceInfo *ti = &vga_interfaces[t];
         if (ti->opt_name && strstart(p, ti->opt_name, &opts)) {
             if (!vga_interface_available(t)) {
-                error_report("%s not available", ti->name);
-                exit(1);
+                error_report_fatal("%s not available", ti->name);
             }
             vga_interface_type = t;
             break;
@@ -2035,8 +2027,7 @@ static void select_vgahw(const char *p)
     }
     if (t == VGA_TYPE_MAX) {
     invalid_vga:
-        error_report("unknown vga type: %s", p);
-        exit(1);
+        error_report_fatal("unknown vga type: %s", p);
     }
     while (*opts) {
         const char *nextopt;
@@ -2120,28 +2111,24 @@ static DisplayType select_display(const char *p)
                 }
             } else {
             invalid_sdl_args:
-                error_report("invalid SDL option string");
-                exit(1);
+                error_report_fatal("invalid SDL option string");
             }
             opts = nextopt;
         }
 #else
-        error_report("SDL support is disabled");
-        exit(1);
+        error_report_fatal("SDL support is disabled");
 #endif
     } else if (strstart(p, "vnc", &opts)) {
         if (*opts == '=') {
             vnc_parse(opts + 1, &error_fatal);
         } else {
-            error_report("VNC requires a display argument vnc=<display>");
-            exit(1);
+            error_report_fatal("VNC requires a display argument vnc=<display>");
         }
     } else if (strstart(p, "curses", &opts)) {
 #ifdef CONFIG_CURSES
         display = DT_CURSES;
 #else
-        error_report("curses support is disabled");
-        exit(1);
+        error_report_fatal("curses support is disabled");
 #endif
     } else if (strstart(p, "gtk", &opts)) {
 #ifdef CONFIG_GTK
@@ -2169,20 +2156,17 @@ static DisplayType select_display(const char *p)
                 }
             } else {
             invalid_gtk_args:
-                error_report("invalid GTK option string");
-                exit(1);
+                error_report_fatal("invalid GTK option string");
             }
             opts = nextopt;
         }
 #else
-        error_report("GTK support is disabled");
-        exit(1);
+        error_report_fatal("GTK support is disabled");
 #endif
     } else if (strstart(p, "none", &opts)) {
         display = DT_NONE;
     } else {
-        error_report("unknown display type");
-        exit(1);
+        error_report_fatal("unknown display type");
     }
 
     return display;
@@ -2356,8 +2340,7 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
     } else if (strcmp(mode, "control") == 0) {
         flags = MONITOR_USE_CONTROL;
     } else {
-        error_report("unknown monitor mode \"%s\"", mode);
-        exit(1);
+        error_report_fatal("unknown monitor mode \"%s\"", mode);
     }
 
     if (qemu_opt_get_bool(opts, "pretty", 0))
@@ -2369,8 +2352,7 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
     chardev = qemu_opt_get(opts, "chardev");
     chr = qemu_chr_find(chardev);
     if (chr == NULL) {
-        error_report("chardev \"%s\" not found", chardev);
-        exit(1);
+        error_report_fatal("chardev \"%s\" not found", chardev);
     }
 
     qemu_chr_fe_claim_no_fail(chr);
@@ -2396,8 +2378,7 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty)
         }
         opts = qemu_chr_parse_compat(label, optarg);
         if (!opts) {
-            error_report("parse error: %s", optarg);
-            exit(1);
+            error_report_fatal("parse error: %s", optarg);
         }
     }
 
@@ -2466,8 +2447,7 @@ static int serial_parse(const char *devname)
     if (strcmp(devname, "none") == 0)
         return 0;
     if (index == MAX_SERIAL_PORTS) {
-        error_report("too many serial ports");
-        exit(1);
+        error_report_fatal("too many serial ports");
     }
     snprintf(label, sizeof(label), "serial%d", index);
     serial_hds[index] = qemu_chr_new(label, devname, NULL);
@@ -2488,8 +2468,7 @@ static int parallel_parse(const char *devname)
     if (strcmp(devname, "none") == 0)
         return 0;
     if (index == MAX_PARALLEL_PORTS) {
-        error_report("too many parallel ports");
-        exit(1);
+        error_report_fatal("too many parallel ports");
     }
     snprintf(label, sizeof(label), "parallel%d", index);
     parallel_hds[index] = qemu_chr_new(label, devname, NULL);
@@ -2512,8 +2491,7 @@ static int virtcon_parse(const char *devname)
     if (strcmp(devname, "none") == 0)
         return 0;
     if (index == MAX_VIRTIO_CONSOLES) {
-        error_report("too many virtio consoles");
-        exit(1);
+        error_report_fatal("too many virtio consoles");
     }
 
     bus_opts = qemu_opts_create(device, NULL, 0, &error_abort);
@@ -2546,8 +2524,7 @@ static int sclp_parse(const char *devname)
         return 0;
     }
     if (index == MAX_SCLP_CONSOLES) {
-        error_report("too many sclp consoles");
-        exit(1);
+        error_report_fatal("too many sclp consoles");
     }
 
     assert(arch_type == QEMU_ARCH_S390X);
@@ -2577,8 +2554,7 @@ static int debugcon_parse(const char *devname)
     }
     opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
     if (!opts) {
-        error_report("already have a debugcon device");
-        exit(1);
+        error_report_fatal("already have a debugcon device");
     }
     qemu_opt_set(opts, "driver", "isa-debugcon", &error_abort);
     qemu_opt_set(opts, "chardev", "debugcon", &error_abort);
@@ -2703,8 +2679,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
     popt = qemu_options;
     for(;;) {
         if (!popt->name) {
-            error_report("invalid option");
-            exit(1);
+            error_report_fatal("invalid option");
         }
         if (!strcmp(popt->name, r + 1))
             break;
@@ -2712,8 +2687,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
     }
     if (popt->flags & HAS_ARG) {
         if (optind >= argc) {
-            error_report("requires an argument");
-            exit(1);
+            error_report_fatal("requires an argument");
         }
         optarg = argv[optind++];
         loc_set_cmdline(argv, optind - 2, 2);
@@ -2841,8 +2815,7 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
     mem_str = qemu_opt_get(opts, "size");
     if (mem_str) {
         if (!*mem_str) {
-            error_report("missing 'size' option value");
-            exit(EXIT_FAILURE);
+            error_report_fatal("missing 'size' option value");
         }
 
         sz = qemu_opt_get_size(opts, "size", ram_size);
@@ -2853,8 +2826,7 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
 
             sz <<= 20;
             if ((sz >> 20) != overflow_check) {
-                error_report("too large 'size' option value");
-                exit(EXIT_FAILURE);
+                error_report_fatal("too large 'size' option value");
             }
         }
     }
@@ -2867,8 +2839,7 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
     sz = QEMU_ALIGN_UP(sz, 8192);
     ram_size = sz;
     if (ram_size != sz) {
-        error_report("ram size too large");
-        exit(EXIT_FAILURE);
+        error_report_fatal("ram size too large");
     }
 
     /* store value for the future use */
@@ -2883,32 +2854,31 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size,
         sz = qemu_opt_get_size(opts, "maxmem", 0);
         slots = qemu_opt_get_number(opts, "slots", 0);
         if (sz < ram_size) {
-            error_report("invalid value of -m option maxmem: "
-                         "maximum memory size (0x%" PRIx64 ") must be at least "
-                         "the initial memory size (0x" RAM_ADDR_FMT ")",
-                         sz, ram_size);
-            exit(EXIT_FAILURE);
+            error_report_fatal("invalid value of -m option maxmem: "
+                               "maximum memory size (0x%" PRIx64
+                               ") must be at least "
+                               "the initial memory size (0x"
+                               RAM_ADDR_FMT ")", sz, ram_size);
         } else if (sz > ram_size) {
             if (!slots) {
-                error_report("invalid value of -m option: maxmem was "
-                             "specified, but no hotplug slots were specified");
-                exit(EXIT_FAILURE);
+                error_report_fatal("invalid value of -m option: maxmem was "
+                                   "specified, but no hotplug slots were "
+                                   "specified");
             }
         } else if (slots) {
-            error_report("invalid value of -m option maxmem: "
-                         "memory slots were specified but maximum memory size "
-                         "(0x%" PRIx64 ") is equal to the initial memory size "
-                         "(0x" RAM_ADDR_FMT ")", sz, ram_size);
-            exit(EXIT_FAILURE);
+            error_report_fatal("invalid value of -m option maxmem: "
+                               "memory slots were specified but maximum "
+                               "memory size (0x%" PRIx64 ") is equal to the "
+                               "initial memory size " "(0x" RAM_ADDR_FMT ")",
+                               sz, ram_size);
         }
 
         *maxram_size = sz;
         *ram_slots = slots;
     } else if ((!maxmem_str && slots_str) ||
             (maxmem_str && !slots_str)) {
-        error_report("invalid -m option value: missing "
-                "'%s' option", slots_str ? "maxmem" : "slots");
-        exit(EXIT_FAILURE);
+        error_report_fatal("invalid -m option value: missing " "'%s' option",
+                           slots_str ? "maxmem" : "slots");
     }
 
     loc_pop(&loc);
@@ -3067,8 +3037,7 @@ int main(int argc, char **argv, char **envp)
 
             popt = lookup_opt(argc, argv, &optarg, &optind);
             if (!(popt->arch_mask & arch_type)) {
-                error_report("Option not supported for this target");
-                exit(1);
+                error_report_fatal("Option not supported for this target");
             }
             switch(popt->index) {
             case QEMU_OPTION_no_kvm_irqchip: {
@@ -3163,8 +3132,7 @@ int main(int argc, char **argv, char **envp)
                         }
                     } else if (*p != '\0') {
                     chs_fail:
-                        error_report("invalid physical CHS format");
-                        exit(1);
+                        error_report_fatal("invalid physical CHS format");
                     }
                     if (hda_opts != NULL) {
                         qemu_opt_set_number(hda_opts, "cyls", cyls,
@@ -3209,8 +3177,7 @@ int main(int argc, char **argv, char **envp)
 #ifdef CONFIG_CURSES
                 display_type = DT_CURSES;
 #else
-                error_report("curses support is disabled");
-                exit(1);
+                error_report_fatal("curses support is disabled");
 #endif
                 break;
             case QEMU_OPTION_portrait:
@@ -3220,8 +3187,8 @@ int main(int argc, char **argv, char **envp)
                 graphic_rotate = strtol(optarg, (char **) &optarg, 10);
                 if (graphic_rotate != 0 && graphic_rotate != 90 &&
                     graphic_rotate != 180 && graphic_rotate != 270) {
-                    error_report("only 90, 180, 270 deg rotation is available");
-                    exit(1);
+                    error_report_fatal("only 90, 180, 270 deg rotation "
+                                       "is available");
                 }
                 break;
             case QEMU_OPTION_kernel:
@@ -3384,8 +3351,7 @@ int main(int argc, char **argv, char **envp)
                     w = strtol(p, (char **)&p, 10);
                     if (w <= 0) {
                     graphic_error:
-                        error_report("invalid resolution or depth");
-                        exit(1);
+                        error_report_fatal("invalid resolution or depth");
                     }
                     if (*p != 'x')
                         goto graphic_error;
@@ -3450,8 +3416,7 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_fsdev:
                 olist = qemu_find_opts("fsdev");
                 if (!olist) {
-                    error_report("fsdev support is disabled");
-                    exit(1);
+                    error_report_fatal("fsdev support is disabled");
                 }
                 opts = qemu_opts_parse_noisily(olist, optarg, true);
                 if (!opts) {
@@ -3465,8 +3430,7 @@ int main(int argc, char **argv, char **envp)
 
                 olist = qemu_find_opts("virtfs");
                 if (!olist) {
-                    error_report("virtfs support is disabled");
-                    exit(1);
+                    error_report_fatal("virtfs support is disabled");
                 }
                 opts = qemu_opts_parse_noisily(olist, optarg, true);
                 if (!opts) {
@@ -3475,16 +3439,14 @@ int main(int argc, char **argv, char **envp)
 
                 if (qemu_opt_get(opts, "fsdriver") == NULL ||
                     qemu_opt_get(opts, "mount_tag") == NULL) {
-                    error_report("Usage: -virtfs fsdriver,mount_tag=tag");
-                    exit(1);
+                    error_report_fatal("Usage: -virtfs fsdriver,mount_tag=tag");
                 }
                 fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
                                          qemu_opt_get(opts, "mount_tag"),
                                          1, NULL);
                 if (!fsdev) {
-                    error_report("duplicate fsdev id: %s",
-                                 qemu_opt_get(opts, "mount_tag"));
-                    exit(1);
+                    error_report_fatal("duplicate fsdev id: %s",
+                                       qemu_opt_get(opts, "mount_tag"));
                 }
 
                 writeout = qemu_opt_get(opts, "writeout");
@@ -3492,9 +3454,8 @@ int main(int argc, char **argv, char **envp)
 #ifdef CONFIG_SYNC_FILE_RANGE
                     qemu_opt_set(fsdev, "writeout", writeout, &error_abort);
 #else
-                    error_report("writeout=immediate not supported "
-                                 "on this platform");
-                    exit(1);
+                    error_report_fatal("writeout=immediate not supported "
+                                       "on this platform");
 #endif
                 }
                 qemu_opt_set(fsdev, "fsdriver",
@@ -3532,8 +3493,7 @@ int main(int argc, char **argv, char **envp)
                 fsdev = qemu_opts_create(qemu_find_opts("fsdev"), "v_synth",
                                          1, NULL);
                 if (!fsdev) {
-                    error_report("duplicate option: %s", "virtfs_synth");
-                    exit(1);
+                    error_report_fatal("duplicate option: %s", "virtfs_synth");
                 }
                 qemu_opt_set(fsdev, "fsdriver", "synth", &error_abort);
 
@@ -3560,8 +3520,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_watchdog_action:
                 if (select_watchdog_action(optarg) == -1) {
-                    error_report("unknown -watchdog-action parameter");
-                    exit(1);
+                    error_report_fatal("unknown -watchdog-action parameter");
                 }
                 break;
             case QEMU_OPTION_virtiocon:
@@ -3604,8 +3563,7 @@ int main(int argc, char **argv, char **envp)
                 display_type = DT_SDL;
                 break;
 #else
-                error_report("SDL support is disabled");
-                exit(1);
+                error_report_fatal("SDL support is disabled");
 #endif
             case QEMU_OPTION_pidfile:
                 pid_file = optarg;
@@ -3710,8 +3668,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_balloon:
                 if (balloon_parse(optarg) < 0) {
-                    error_report("unknown -balloon argument %s", optarg);
-                    exit(1);
+                    error_report_fatal("unknown -balloon argument %s", optarg);
                 }
                 break;
             case QEMU_OPTION_no_reboot:
@@ -3725,15 +3682,14 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_uuid:
                 if(qemu_uuid_parse(optarg, qemu_uuid) < 0) {
-                    error_report("failed to parse UUID string: wrong format");
-                    exit(1);
+                    error_report_fatal("failed to parse UUID string: "
+                                       "wrong format");
                 }
                 qemu_uuid_set = true;
                 break;
             case QEMU_OPTION_option_rom:
                 if (nb_option_roms >= MAX_OPTION_ROMS) {
-                    error_report("too many option ROMs");
-                    exit(1);
+                    error_report_fatal("too many option ROMs");
                 }
                 opts = qemu_opts_parse_noisily(qemu_find_opts("option-rom"),
                                                optarg, true);
@@ -3744,8 +3700,7 @@ int main(int argc, char **argv, char **envp)
                 option_rom[nb_option_roms].bootindex =
                     qemu_opt_get_number(opts, "bootindex", -1);
                 if (!option_rom[nb_option_roms].name) {
-                    error_report("Option ROM file is not specified");
-                    exit(1);
+                    error_report_fatal("Option ROM file is not specified");
                 }
                 nb_option_roms++;
                 break;
@@ -3769,9 +3724,8 @@ int main(int argc, char **argv, char **envp)
                         } else  if (strcmp("auto", target) == 0) {
                             semihosting.target = SEMIHOSTING_TARGET_AUTO;
                         } else {
-                            error_report("unsupported semihosting-config %s",
-                                         optarg);
-                            exit(1);
+                            error_report_fatal("unsupported semihosting-"
+                                               "config %s", optarg);
                         }
                     } else {
                         semihosting.target = SEMIHOSTING_TARGET_AUTO;
@@ -3780,8 +3734,8 @@ int main(int argc, char **argv, char **envp)
                     qemu_opt_foreach(opts, add_semihosting_arg,
                                      &semihosting, NULL);
                 } else {
-                    error_report("unsupported semihosting-config %s", optarg);
-                    exit(1);
+                    error_report_fatal("unsupported semihosting-config %s",
+                                       optarg);
                 }
                 break;
             case QEMU_OPTION_tdf:
@@ -3796,8 +3750,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_prom_env:
                 if (nb_prom_envs >= MAX_PROM_ENVS) {
-                    error_report("too many prom variables");
-                    exit(1);
+                    error_report_fatal("too many prom variables");
                 }
                 prom_envs[nb_prom_envs] = optarg;
                 nb_prom_envs++;
@@ -3845,22 +3798,19 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_xen_domid:
                 if (!(xen_available())) {
-                    error_report("Option not supported for this target");
-                    exit(1);
+                    error_report_fatal("Option not supported for this target");
                 }
                 xen_domid = atoi(optarg);
                 break;
             case QEMU_OPTION_xen_create:
                 if (!(xen_available())) {
-                    error_report("Option not supported for this target");
-                    exit(1);
+                    error_report_fatal("Option not supported for this target");
                 }
                 xen_mode = XEN_CREATE;
                 break;
             case QEMU_OPTION_xen_attach:
                 if (!(xen_available())) {
-                    error_report("Option not supported for this target");
-                    exit(1);
+                    error_report_fatal("Option not supported for this target");
                 }
                 xen_mode = XEN_ATTACH;
                 break;
@@ -3872,17 +3822,15 @@ int main(int argc, char **argv, char **envp)
                 {
                     int ret = qemu_read_config_file(optarg);
                     if (ret < 0) {
-                        error_report("read config %s: %s", optarg,
-                                     strerror(-ret));
-                        exit(1);
+                        error_report_fatal("read config %s: %s", optarg,
+                                           strerror(-ret));
                     }
                     break;
                 }
             case QEMU_OPTION_spice:
                 olist = qemu_find_opts("spice");
                 if (!olist) {
-                    error_report("spice support is disabled");
-                    exit(1);
+                    error_report_fatal("spice support is disabled");
                 }
                 opts = qemu_opts_parse_noisily(olist, optarg, false);
                 if (!opts) {
@@ -3898,9 +3846,8 @@ int main(int argc, char **argv, char **envp)
                     } else {
                         fp = fopen(optarg, "w");
                         if (fp == NULL) {
-                            error_report("open %s: %s", optarg,
-                                         strerror(errno));
-                            exit(1);
+                            error_report_fatal("open %s: %s", optarg,
+                                               strerror(errno));
                         }
                     }
                     qemu_config_write(fp);
@@ -3930,9 +3877,8 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
 #else
-                error_report("File descriptor passing is disabled on this "
-                             "platform");
-                exit(1);
+                error_report_fatal("File descriptor passing is disabled "
+                                   "on this platform");
 #endif
                 break;
             case QEMU_OPTION_object:
@@ -3960,14 +3906,12 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_dump_vmstate:
                 if (vmstate_dump_file) {
-                    error_report("only one '-dump-vmstate' "
-                                 "option may be given");
-                    exit(1);
+                    error_report_fatal("only one '-dump-vmstate' "
+                                       "option may be given");
                 }
                 vmstate_dump_file = fopen(optarg, "w");
                 if (vmstate_dump_file == NULL) {
-                    error_report("open %s: %s", optarg, strerror(errno));
-                    exit(1);
+                    error_report_fatal("open %s: %s", optarg, strerror(errno));
                 }
                 break;
             default:
@@ -4082,10 +4026,10 @@ int main(int argc, char **argv, char **envp)
 
     machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */
     if (max_cpus > machine_class->max_cpus) {
-        error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
-                     "supported by machine '%s' (%d)", max_cpus,
-                     machine_class->name, machine_class->max_cpus);
-        exit(1);
+        error_report_fatal("Number of SMP CPUs requested (%d) exceeds max CPUs "
+                           "supported by machine '%s' (%d)",
+                           max_cpus, machine_class->name,
+                           machine_class->max_cpus);
     }
 
     /*
@@ -4145,13 +4089,11 @@ int main(int argc, char **argv, char **envp)
         if (nographic
             && (default_parallel || default_serial
                 || default_monitor || default_virtcon)) {
-            error_report("-nographic cannot be used with -daemonize");
-            exit(1);
+            error_report_fatal("-nographic cannot be used with -daemonize");
         }
 #ifdef CONFIG_CURSES
         if (display_type == DT_CURSES) {
-            error_report("curses display cannot be used with -daemonize");
-            exit(1);
+            error_report_fatal("curses display cannot be used with -daemonize");
         }
 #endif
     }
@@ -4230,9 +4172,8 @@ int main(int argc, char **argv, char **envp)
 #if defined(CONFIG_OPENGL)
         error_report("OpenGL is not supported by the display");
 #else
-        error_report("OpenGL support is disabled");
+        error_report_fatal("OpenGL support is disabled");
 #endif
-        exit(1);
     }
 
     page_size_init();
@@ -4257,8 +4198,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 
     if (pid_file && qemu_create_pidfile(pid_file) != 0) {
-        error_report("could not acquire pid file: %s", strerror(errno));
-        exit(1);
+        error_report_fatal("could not acquire pid file: %s", strerror(errno));
     }
 
     if (qemu_opts_foreach(qemu_find_opts("device"),
@@ -4313,18 +4253,15 @@ int main(int argc, char **argv, char **envp)
     linux_boot = (kernel_filename != NULL);
 
     if (!linux_boot && *kernel_cmdline != '\0') {
-        error_report("-append only allowed with -kernel option");
-        exit(1);
+        error_report_fatal("-append only allowed with -kernel option");
     }
 
     if (!linux_boot && initrd_filename != NULL) {
-        error_report("-initrd only allowed with -kernel option");
-        exit(1);
+        error_report_fatal("-initrd only allowed with -kernel option");
     }
 
     if (!linux_boot && qemu_opt_get(machine_opts, "dtb")) {
-        error_report("-dtb only allowed with -kernel option");
-        exit(1);
+        error_report_fatal("-dtb only allowed with -kernel option");
     }
 
     if (semihosting_enabled() && !semihosting_get_argc() && kernel_filename) {
@@ -4340,8 +4277,7 @@ int main(int argc, char **argv, char **envp)
     cpu_ticks_init();
     if (icount_opts) {
         if (kvm_enabled() || xen_enabled()) {
-            error_report("-icount is not allowed with kvm or xen");
-            exit(1);
+            error_report_fatal("-icount is not allowed with kvm or xen");
         }
         configure_icount(icount_opts, &error_abort);
         qemu_opts_del(icount_opts);
@@ -4378,8 +4314,7 @@ int main(int argc, char **argv, char **envp)
     if (!xen_enabled()) {
         /* On 32-bit hosts, QEMU is limited by virtual address space */
         if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
-            error_report("at most 2047 MB RAM can be simulated");
-            exit(1);
+            error_report_fatal("at most 2047 MB RAM can be simulated");
         }
     }
 
@@ -4562,8 +4497,7 @@ int main(int argc, char **argv, char **envp)
     qemu_run_machine_init_done_notifiers();
 
     if (rom_check_and_register_reset() != 0) {
-        error_report("rom check and register reset failed");
-        exit(1);
+        error_report_fatal("rom check and register reset failed");
     }
 
     replay_start();
diff --git a/xen-hvm.c b/xen-hvm.c
index 2f348ed..0f1cbbf 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -1319,8 +1319,7 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
     return;
 
 err:
-    error_report("xen hardware virtual machine initialisation failed");
-    exit(1);
+    error_report_fatal("xen hardware virtual machine initialisation failed");
 }
 
 void destroy_hvm_domain(bool reboot)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH v4 4/4] error-report: leverage error_report_abort()
  2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
                   ` (2 preceding siblings ...)
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 3/4] error-report: leverage error_report_fatal() Peter Xu
@ 2016-09-07  6:06 ` Peter Xu
  2016-09-07  6:39 ` [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Fam Zheng
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Peter Xu @ 2016-09-07  6:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: armbru, peter.maydell, pbonzini, famz, peterx

Two cases that can leverage error_report_abort():

Case 1:

  error_report(...);
  abort();

Case 2:

  error_setg(&error_abort, ...);

This patch converts these cases to use error_report_abort().

Script error_report_abort.cocci is added to automate the convertion.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 block/qcow2.c                               |  4 ++--
 hw/block/fdc.c                              |  6 +++---
 hw/i386/kvm/pci-assign.c                    |  4 ++--
 hw/intc/xics.c                              |  5 ++---
 hw/pci/pci.c                                |  3 +--
 hw/ppc/spapr_drc.c                          |  2 +-
 hw/vfio/platform.c                          | 10 ++++------
 net/netmap.c                                |  5 ++---
 net/tap-linux.c                             | 10 ++++++----
 scripts/coccinelle/error_report_abort.cocci | 14 ++++++++++++++
 target-ppc/translate_init.c                 |  3 +--
 vl.c                                        |  7 +++----
 12 files changed, 41 insertions(+), 32 deletions(-)
 create mode 100644 scripts/coccinelle/error_report_abort.cocci

diff --git a/block/qcow2.c b/block/qcow2.c
index 91ef4df..d491564 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2254,8 +2254,8 @@ static int qcow2_create2(const char *filename, int64_t total_size,
         goto out;
 
     } else if (ret != 0) {
-        error_report("Huh, first cluster in empty image is already in use?");
-        abort();
+        error_report_abort("Huh, first cluster in empty image is "
+                           "already in use?");
     }
 
     /* Create a full header (including things like feature table) */
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index f73af7d..14d2f20 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -372,9 +372,9 @@ static int pick_geometry(FDrive *drv)
 
     /* No match of any kind found -- fd_format is misconfigured, abort. */
     if (match == -1) {
-        error_setg(&error_abort, "No candidate geometries present in table "
-                   " for floppy drive type '%s'",
-                   FloppyDriveType_lookup[drv->drive]);
+        error_report_abort("No candidate geometries present in table "
+                           " for floppy drive type '%s'",
+                           FloppyDriveType_lookup[drv->drive]);
     }
 
     parse = &(fd_formats[match]);
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 8238fbc..e27f307 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -465,8 +465,8 @@ static void assigned_dev_register_regions(PCIRegion *io_regions,
              * so should return EINVAL for a 3 byte read */
             ret = pread(pci_dev->v_addrs[i].region->resource_fd, &val, 3, 0);
             if (ret >= 0) {
-                error_report("Unexpected return from I/O port read: %d", ret);
-                abort();
+                error_report_abort("Unexpected return from I/O port read: %d",
+                                   ret);
             } else if (errno != EINVAL) {
                 error_report("Kernel doesn't support ioport resource "
                              "access, hiding this region.");
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index cd48f42..86e5ddc8 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -84,9 +84,8 @@ void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
         break;
 
     default:
-        error_report("XICS interrupt controller does not support this CPU "
-                     "bus model");
-        abort();
+        error_report_abort("XICS interrupt controller does not support "
+                           "this CPU bus model");
     }
 }
 
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 0642def..f54b43c 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2606,8 +2606,7 @@ MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
         msg = msi_get_message(dev, vector);
     } else {
         /* Should never happen */
-        error_report("%s: unknown interrupt type", __func__);
-        abort();
+        error_report_abort("%s: unknown interrupt type", __func__);
     }
     return msg;
 }
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 26a0679..8d59a8d 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -327,7 +327,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
             break;
         }
         default:
-            error_setg(&error_abort, "device FDT in unexpected state: %d", tag);
+            error_report_abort("device FDT in unexpected state: %d", tag);
         }
         fdt_offset = fdt_offset_next;
     } while (fdt_depth != 0);
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index a559e7b..1190c92 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -339,9 +339,8 @@ static void vfio_start_eventfd_injection(SysBusDevice *sbdev, qemu_irq irq)
 
     ret = vfio_set_trigger_eventfd(intp, vfio_intp_interrupt);
     if (ret) {
-        error_report("vfio: failed to start eventfd signaling for IRQ %d: %m",
-                     intp->pin);
-        abort();
+        error_report_abort("vfio: failed to start eventfd signaling "
+                           "for IRQ %d: %m", intp->pin);
     }
 }
 
@@ -431,9 +430,8 @@ static void vfio_start_irqfd_injection(SysBusDevice *sbdev, qemu_irq irq)
     return;
 fail_vfio:
     kvm_irqchip_remove_irqfd_notifier(kvm_state, intp->interrupt, irq);
-    error_report("vfio: failed to start eventfd signaling for IRQ %d: %m",
-                 intp->pin);
-    abort();
+    error_report_abort("vfio: failed to start eventfd signaling for IRQ %d: %m",
+                       intp->pin);
 fail_irqfd:
     vfio_start_eventfd_injection(sbdev, irq);
     return;
diff --git a/net/netmap.c b/net/netmap.c
index 2d11a8f..53ef57e 100644
--- a/net/netmap.c
+++ b/net/netmap.c
@@ -352,9 +352,8 @@ static bool netmap_has_vnet_hdr_len(NetClientState *nc, int len)
 
     /* Restore the previous length. */
     if (netmap_fd_set_vnet_hdr_len(s, prev_len)) {
-        error_report("Failed to restore vnet-hdr length %d on %s: %s",
-                     prev_len, s->ifname, strerror(errno));
-        abort();
+        error_report_abort("Failed to restore vnet-hdr length %d on %s: %s",
+                           prev_len, s->ifname, strerror(errno));
     }
 
     return true;
diff --git a/net/tap-linux.c b/net/tap-linux.c
index a503fa9..f7a6808 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -213,8 +213,9 @@ int tap_fd_set_vnet_le(int fd, int is_le)
         return -errno;
     }
 
-    error_report("TUNSETVNETLE ioctl() failed: %s.", strerror(errno));
-    abort();
+    error_report_abort("TUNSETVNETLE ioctl() failed: %s.", strerror(errno));
+    /* Not reach here. */
+    return -1;
 }
 
 int tap_fd_set_vnet_be(int fd, int is_be)
@@ -230,8 +231,9 @@ int tap_fd_set_vnet_be(int fd, int is_be)
         return -errno;
     }
 
-    error_report("TUNSETVNETBE ioctl() failed: %s.", strerror(errno));
-    abort();
+    error_report_abort("TUNSETVNETBE ioctl() failed: %s.", strerror(errno));
+    /* Not reach here. */
+    return -1;
 }
 
 void tap_fd_set_offload(int fd, int csum, int tso4,
diff --git a/scripts/coccinelle/error_report_abort.cocci b/scripts/coccinelle/error_report_abort.cocci
new file mode 100644
index 0000000..cd95fa5
--- /dev/null
+++ b/scripts/coccinelle/error_report_abort.cocci
@@ -0,0 +1,14 @@
+@@
+expression list X;
+@@
+
+-error_report(X);
+-abort();
++error_report_abort(X);
+
+@@
+expression list X;
+@@
+
+-error_setg(&error_abort, X);
++error_report_abort(X);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 7a9b15e..4007bb6 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8446,8 +8446,7 @@ static void powerpc_get_compat(Object *obj, Visitor *v, const char *name,
     case 0:
         break;
     default:
-        error_report("Internal error: compat is set to %x", *max_compat);
-        abort();
+        error_report_abort("Internal error: compat is set to %x", *max_compat);
         break;
     }
 
diff --git a/vl.c b/vl.c
index 6939b99..cd10a3b 100644
--- a/vl.c
+++ b/vl.c
@@ -676,10 +676,9 @@ void runstate_set(RunState new_state)
     }
 
     if (!runstate_valid_transitions[current_run_state][new_state]) {
-        error_report("invalid runstate transition: '%s' -> '%s'",
-                     RunState_lookup[current_run_state],
-                     RunState_lookup[new_state]);
-        abort();
+        error_report_abort("invalid runstate transition: '%s' -> '%s'",
+                           RunState_lookup[current_run_state],
+                           RunState_lookup[new_state]);
     }
     trace_runstate_set(new_state);
     current_run_state = new_state;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
                   ` (3 preceding siblings ...)
  2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 4/4] error-report: leverage error_report_abort() Peter Xu
@ 2016-09-07  6:39 ` Fam Zheng
  2016-09-07  9:23 ` Alex Bennée
  2016-09-09 17:05 ` Markus Armbruster
  6 siblings, 0 replies; 17+ messages in thread
From: Fam Zheng @ 2016-09-07  6:39 UTC (permalink / raw)
  To: Peter Xu; +Cc: qemu-devel, armbru, peter.maydell, pbonzini

On Wed, 09/07 14:06, Peter Xu wrote:
> v4 changes:
> - remove two standard headers since they are included in osdep.h
>   already [Fam]
> - make sure it passes build on all platforms (no --target-list
>   specified during configure)

Reviewed-by: Fam Zheng <famz@redhat.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
                   ` (4 preceding siblings ...)
  2016-09-07  6:39 ` [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Fam Zheng
@ 2016-09-07  9:23 ` Alex Bennée
  2016-09-07  9:33   ` Fam Zheng
  2016-09-09 17:05 ` Markus Armbruster
  6 siblings, 1 reply; 17+ messages in thread
From: Alex Bennée @ 2016-09-07  9:23 UTC (permalink / raw)
  To: Peter Xu; +Cc: qemu-devel, peter.maydell, famz, armbru, pbonzini


Peter Xu <peterx@redhat.com> writes:

> v4 changes:
> - remove two standard headers since they are included in osdep.h
>   already [Fam]
> - make sure it passes build on all platforms (no --target-list
>   specified during configure)
>
> v3 changes:
> - implement error_report_fatal using function [Markus]
> - provide error_report_abort as well in seperate patch [Markus, Fam]
>
> We have many use cases that first print some error messages, then
> quit (by either exit() or abort()). This series introduce two helper
> functions for that.
>
> The old formats are mostly one of the following:
>
> Case one:
>
>   error_report(...);
>   exit(1|EXIT_FAILURE) | abort();
>
> Case two:
>
>   error_setg(&error_{fatal|abort}, ...);
>
> And we can convert either of the above cases into:
>
>   error_report_{fatal|abort}(...);

Last time I needed to do error reporting I was told the error_setg
method was the correct way to do it and the report/exit case made sense
only in the top level. Before we add even more error reporting
primitives can we update HACKING (or possibly add somethings to docs/)
that describes when and where the various error report mechanisms should
be used?

>
> Two coccinelle scripts are created to help automate the work, plus
> some manual tweaks:
>
> 1. very long strings, fix for over-80-chars issues, to make sure it
>    passes checkpatch.pl.
>
> 2. add "return XXX" for some non-void retcode functions.
>
> The first two patches introduce the functions. The latter two apply
> them.
>
> Peter Xu (4):
>   error-report: provide error_report_fatal()
>   error-report: provide error_report_abort()
>   error-report: leverage error_report_fatal()
>   error-report: leverage error_report_abort()
>
>  arch_init.c                                 |   8 +-
>  block/qcow2.c                               |   4 +-
>  bootdevice.c                                |   4 +-
>  cpus.c                                      |   3 +-
>  device_tree.c                               |  61 +++---
>  hw/9pfs/9p.c                                |   3 +-
>  hw/alpha/dp264.c                            |  14 +-
>  hw/arm/armv7m.c                             |   3 +-
>  hw/arm/digic_boards.c                       |   6 +-
>  hw/arm/fsl-imx6.c                           |   5 +-
>  hw/arm/highbank.c                           |   6 +-
>  hw/arm/raspi.c                              |   7 +-
>  hw/arm/sabrelite.c                          |   9 +-
>  hw/arm/strongarm.c                          |   6 +-
>  hw/arm/sysbus-fdt.c                         |  41 ++--
>  hw/arm/vexpress.c                           |  14 +-
>  hw/arm/virt.c                               |  45 ++---
>  hw/arm/xlnx-ep108.c                         |  10 +-
>  hw/block/fdc.c                              |   6 +-
>  hw/block/tc58128.c                          |   3 +-
>  hw/block/virtio-blk.c                       |   9 +-
>  hw/char/exynos4210_uart.c                   |   9 +-
>  hw/core/machine.c                           |   7 +-
>  hw/core/platform-bus.c                      |   8 +-
>  hw/i386/intel_iommu.c                       |   5 +-
>  hw/i386/kvm/pci-assign.c                    |   4 +-
>  hw/i386/pc.c                                |  36 ++--
>  hw/i386/pc_piix.c                           |   3 +-
>  hw/i386/x86-iommu.c                         |   5 +-
>  hw/ide/core.c                               |   5 +-
>  hw/intc/ioapic.c                            |   5 +-
>  hw/intc/xics.c                              |   5 +-
>  hw/intc/xics_kvm.c                          |  17 +-
>  hw/m68k/an5206.c                            |   3 +-
>  hw/microblaze/boot.c                        |   5 +-
>  hw/mips/mips_fulong2e.c                     |   3 +-
>  hw/mips/mips_jazz.c                         |   3 +-
>  hw/mips/mips_malta.c                        |  26 ++-
>  hw/mips/mips_mipssim.c                      |   6 +-
>  hw/net/virtio-net.c                         |  28 ++-
>  hw/nvram/fw_cfg.c                           |   5 +-
>  hw/pci/pci.c                                |   8 +-
>  hw/ppc/e500.c                               |   5 +-
>  hw/ppc/mac_newworld.c                       |  14 +-
>  hw/ppc/mac_oldworld.c                       |  18 +-
>  hw/ppc/mpc8544ds.c                          |   4 +-
>  hw/ppc/ppc405_boards.c                      |  14 +-
>  hw/ppc/prep.c                               |  11 +-
>  hw/ppc/spapr.c                              |  89 ++++-----
>  hw/ppc/spapr_drc.c                          |   2 +-
>  hw/ppc/virtex_ml507.c                       |   5 +-
>  hw/scsi/vhost-scsi.c                        |  11 +-
>  hw/scsi/virtio-scsi.c                       |  10 +-
>  hw/sh4/shix.c                               |   3 +-
>  hw/smbios/smbios.c                          |  42 ++---
>  hw/sparc/sun4m.c                            |  19 +-
>  hw/tricore/tricore_testboard.c              |   8 +-
>  hw/unicore32/puv3.c                         |   9 +-
>  hw/vfio/platform.c                          |  10 +-
>  hw/virtio/virtio.c                          |  45 ++---
>  hw/xtensa/sim.c                             |   5 +-
>  hw/xtensa/xtfpga.c                          |  17 +-
>  include/qemu/error-report.h                 |   2 +
>  net/netmap.c                                |   5 +-
>  net/tap-linux.c                             |  10 +-
>  numa.c                                      |  22 +--
>  qemu-img.c                                  |  16 +-
>  qemu-io.c                                   |   9 +-
>  qemu-nbd.c                                  | 116 +++++-------
>  replay/replay-char.c                        |   9 +-
>  replay/replay-events.c                      |  12 +-
>  replay/replay-internal.c                    |   4 +-
>  replay/replay-time.c                        |   5 +-
>  replay/replay.c                             |   9 +-
>  scripts/coccinelle/error_report_abort.cocci |  14 ++
>  scripts/coccinelle/error_report_fatal.cocci |  20 ++
>  target-arm/machine.c                        |   5 +-
>  target-i386/kvm.c                           |  10 +-
>  target-ppc/kvm.c                            |   7 +-
>  target-ppc/translate_init.c                 |   3 +-
>  target-s390x/cpu.c                          |   5 +-
>  target-s390x/kvm.c                          |   8 +-
>  target-s390x/mmu_helper.c                   |   5 +-
>  trace/control.c                             |   6 +-
>  ui/spice-core.c                             |  43 ++---
>  util/qemu-error.c                           |  22 +++
>  vl.c                                        | 279 +++++++++++-----------------
>  xen-hvm.c                                   |   3 +-
>  88 files changed, 622 insertions(+), 831 deletions(-)
>  create mode 100644 scripts/coccinelle/error_report_abort.cocci
>  create mode 100644 scripts/coccinelle/error_report_fatal.cocci


--
Alex Bennée

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-07  9:23 ` Alex Bennée
@ 2016-09-07  9:33   ` Fam Zheng
  2016-09-07 10:42     ` Peter Xu
  2016-09-07 12:39     ` Lluís Vilanova
  0 siblings, 2 replies; 17+ messages in thread
From: Fam Zheng @ 2016-09-07  9:33 UTC (permalink / raw)
  To: Alex Bennée; +Cc: Peter Xu, qemu-devel, peter.maydell, armbru, pbonzini

On Wed, 09/07 10:23, Alex Bennée wrote:
> Last time I needed to do error reporting I was told the error_setg
> method was the correct way to do it and the report/exit case made sense
> only in the top level. Before we add even more error reporting
> primitives can we update HACKING (or possibly add somethings to docs/)
> that describes when and where the various error report mechanisms should
> be used?

FWIW, the comment of error_setg clarifies the recommended usage now:

...
>  * 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, ...)                              \
...

Fam

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-07  9:33   ` Fam Zheng
@ 2016-09-07 10:42     ` Peter Xu
  2016-09-07 12:39     ` Lluís Vilanova
  1 sibling, 0 replies; 17+ messages in thread
From: Peter Xu @ 2016-09-07 10:42 UTC (permalink / raw)
  To: Fam Zheng; +Cc: Alex Bennée, qemu-devel, peter.maydell, armbru, pbonzini

On Wed, Sep 07, 2016 at 05:33:08PM +0800, Fam Zheng wrote:
> On Wed, 09/07 10:23, Alex Bennée wrote:
> > Last time I needed to do error reporting I was told the error_setg
> > method was the correct way to do it and the report/exit case made sense
> > only in the top level. Before we add even more error reporting
> > primitives can we update HACKING (or possibly add somethings to docs/)
> > that describes when and where the various error report mechanisms should
> > be used?
> 
> FWIW, the comment of error_setg clarifies the recommended usage now:
> 
> ...
> >  * 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, ...)                              \

I can update both HACKING and above comment to mention about the new
interface in v5 (if we will have a v5) by appending a new patch for
the docs. Otherwise, I can post the patch seperately when needed.

Thanks,

-- peterx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-07  9:33   ` Fam Zheng
  2016-09-07 10:42     ` Peter Xu
@ 2016-09-07 12:39     ` Lluís Vilanova
  2016-09-07 13:48       ` Markus Armbruster
  1 sibling, 1 reply; 17+ messages in thread
From: Lluís Vilanova @ 2016-09-07 12:39 UTC (permalink / raw)
  To: Fam Zheng
  Cc: Alex Bennée, peter.maydell, pbonzini, qemu-devel, Peter Xu, armbru

Fam Zheng writes:

> On Wed, 09/07 10:23, Alex Bennée wrote:
>> Last time I needed to do error reporting I was told the error_setg
>> method was the correct way to do it and the report/exit case made sense
>> only in the top level. Before we add even more error reporting
>> primitives can we update HACKING (or possibly add somethings to docs/)
>> that describes when and where the various error report mechanisms should
>> be used?

> FWIW, the comment of error_setg clarifies the recommended usage now:

> ...
>> * 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, ...)                              \
> ...

Doesn't this series then contradict this comment?

Cheers,
  Lluis

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-07 12:39     ` Lluís Vilanova
@ 2016-09-07 13:48       ` Markus Armbruster
  0 siblings, 0 replies; 17+ messages in thread
From: Markus Armbruster @ 2016-09-07 13:48 UTC (permalink / raw)
  To: Fam Zheng; +Cc: Alex Bennée, peter.maydell, pbonzini, qemu-devel, Peter Xu

Lluís Vilanova <vilanova@ac.upc.edu> writes:

> Fam Zheng writes:
>
>> On Wed, 09/07 10:23, Alex Bennée wrote:
>>> Last time I needed to do error reporting I was told the error_setg
>>> method was the correct way to do it and the report/exit case made sense
>>> only in the top level. Before we add even more error reporting
>>> primitives can we update HACKING (or possibly add somethings to docs/)
>>> that describes when and where the various error report mechanisms should
>>> be used?
>
>> FWIW, the comment of error_setg clarifies the recommended usage now:
>
>> ...
>>> * 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, ...)                              \
>> ...
>
> Doesn't this series then contradict this comment?

Yes, but I asked Peter for it:

    Regarding error_report_abort(): in my opinion, printing pretty
    messages right before abort() is largely a waste of time.  But if
    people insist on doing it, then the error subsystem may have to
    support it.  Would you be willing to track down such usage, so we
    can make an informed decision?

http://lists.gnu.org/archive/html/qemu-devel/2016-08/msg02930.html

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
                   ` (5 preceding siblings ...)
  2016-09-07  9:23 ` Alex Bennée
@ 2016-09-09 17:05 ` Markus Armbruster
  2016-09-09 17:19   ` Daniel P. Berrange
                     ` (2 more replies)
  6 siblings, 3 replies; 17+ messages in thread
From: Markus Armbruster @ 2016-09-09 17:05 UTC (permalink / raw)
  To: Peter Xu; +Cc: qemu-devel, peter.maydell, famz, pbonzini

Peter Xu <peterx@redhat.com> writes:

> v4 changes:
> - remove two standard headers since they are included in osdep.h
>   already [Fam]
> - make sure it passes build on all platforms (no --target-list
>   specified during configure)
>
> v3 changes:
> - implement error_report_fatal using function [Markus]
> - provide error_report_abort as well in seperate patch [Markus, Fam]
>
> We have many use cases that first print some error messages, then
> quit (by either exit() or abort()). This series introduce two helper
> functions for that.
>
> The old formats are mostly one of the following:
>
> Case one:
>
>   error_report(...);
>   exit(1|EXIT_FAILURE) | abort();
>
> Case two:
>
>   error_setg(&error_{fatal|abort}, ...);
>
> And we can convert either of the above cases into:
>
>   error_report_{fatal|abort}(...);
>
> Two coccinelle scripts are created to help automate the work, plus
> some manual tweaks:
>
> 1. very long strings, fix for over-80-chars issues, to make sure it
>    passes checkpatch.pl.
>
> 2. add "return XXX" for some non-void retcode functions.
>
> The first two patches introduce the functions. The latter two apply
> them.

You effectively propose to revise this coding rule from error.h:

 * 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().

If we accept your proposal, you get to add a patch to update the rule :)

We've discussed the preferred way to report fatal errors to the human
user before.  With actual patches, we can see how a change of rules
changes the code.  Do we like the change shown by this patch set?

I believe there are a number of separate issues to discuss here:

* Shall we get rid of error_setg(&error_fatal, ...)?

  This is a no-brainer for me.  Such a simple thing should be done in
  one way, not two ways.  I count 14 instances of
  error_setg(&error_fatal, ...), but more than 300 of error_report(...);
  exit(1).

* Shall we fuse error_report() and exit() into error_report_fatal()?

  Saves ~200 lines, not counting the Coccinelle semantic patch.

  I think the real question is what's easier to read and to write.  Do
  you prefer something like

                    error_report("ISA bus not available for %s", c->name);
                    exit(1);

  or something like

                    error_report_fatal("ISA bus not available for %s",
                                       c->name);

  The second form saves a tiny bit of instruction space, I guess.

* Shall we get rid of error_setg(&error_abort, ...)?

  Getting rid of it is again a no-brainer, but what to replace it with
  isn't.

  In my personal opinion, abort() is a perfectly fine way to handle
  "this cannot happen" conditions, and printing pretty messages right
  before abort() is a waste of time.  If the abort() happens, the
  program is broken, and all the end user needs to know is that he needs
  to find someone to debug and fix it.  If the end user really needs to
  know more, use of abort() is usually wrong.

  But others have different opinions.  If you want to print pretty
  messages before abort(), you get to print them.

  The question is whether to provide a fused error_report_abort().  I'd
  be willing to provide it just for symmetry with error_report_fatal(),
  if we decide we want error_report_fatal().

Opinions?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-09 17:05 ` Markus Armbruster
@ 2016-09-09 17:19   ` Daniel P. Berrange
  2016-09-12  8:02     ` Markus Armbruster
  2016-09-12  5:33   ` Peter Xu
  2016-09-12 19:49   ` Eric Blake
  2 siblings, 1 reply; 17+ messages in thread
From: Daniel P. Berrange @ 2016-09-09 17:19 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: Peter Xu, peter.maydell, famz, qemu-devel, pbonzini

On Fri, Sep 09, 2016 at 07:05:04PM +0200, Markus Armbruster wrote:
> Peter Xu <peterx@redhat.com> writes:
> 
> > v4 changes:
> > - remove two standard headers since they are included in osdep.h
> >   already [Fam]
> > - make sure it passes build on all platforms (no --target-list
> >   specified during configure)
> >
> > v3 changes:
> > - implement error_report_fatal using function [Markus]
> > - provide error_report_abort as well in seperate patch [Markus, Fam]
> >
> > We have many use cases that first print some error messages, then
> > quit (by either exit() or abort()). This series introduce two helper
> > functions for that.
> >
> > The old formats are mostly one of the following:
> >
> > Case one:
> >
> >   error_report(...);
> >   exit(1|EXIT_FAILURE) | abort();
> >
> > Case two:
> >
> >   error_setg(&error_{fatal|abort}, ...);
> >
> > And we can convert either of the above cases into:
> >
> >   error_report_{fatal|abort}(...);
> >
> > Two coccinelle scripts are created to help automate the work, plus
> > some manual tweaks:
> >
> > 1. very long strings, fix for over-80-chars issues, to make sure it
> >    passes checkpatch.pl.
> >
> > 2. add "return XXX" for some non-void retcode functions.
> >
> > The first two patches introduce the functions. The latter two apply
> > them.
> 
> You effectively propose to revise this coding rule from error.h:
> 
>  * 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().
> 
> If we accept your proposal, you get to add a patch to update the rule :)
> 
> We've discussed the preferred way to report fatal errors to the human
> user before.  With actual patches, we can see how a change of rules
> changes the code.  Do we like the change shown by this patch set?
> 
> I believe there are a number of separate issues to discuss here:
> 
> * Shall we get rid of error_setg(&error_fatal, ...)?
> 
>   This is a no-brainer for me.  Such a simple thing should be done in
>   one way, not two ways.  I count 14 instances of
>   error_setg(&error_fatal, ...), but more than 300 of error_report(...);
>   exit(1).

NB, arguably 99% of the usage of error_setg(&error_fatal) are in
fact cases where code ought to be eventually converted to accept
an "Error **errp" parameter and let the caller decide whether to
exit or not.

IOW, if we take this approach today we'll change

   error_setg(&error_fatal, "....");

into

   error_report_fatal("....");

and then later potentially change it back again to

   error_setg(errp, "....");


This isn't the end of the world, but I'm just not convinced that
the intermediate change to error_report_fatal() buys us anything
positive overall.

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-09 17:05 ` Markus Armbruster
  2016-09-09 17:19   ` Daniel P. Berrange
@ 2016-09-12  5:33   ` Peter Xu
  2016-09-12 19:49   ` Eric Blake
  2 siblings, 0 replies; 17+ messages in thread
From: Peter Xu @ 2016-09-12  5:33 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel, peter.maydell, famz, pbonzini

On Fri, Sep 09, 2016 at 07:05:04PM +0200, Markus Armbruster wrote:

[...]

> You effectively propose to revise this coding rule from error.h:
> 
>  * 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().
> 
> If we accept your proposal, you get to add a patch to update the rule :)

Yep, I was planning to add it in a newer version when needed, or post
it seperately after this series.

[...]

> * Shall we fuse error_report() and exit() into error_report_fatal()?
> 
>   Saves ~200 lines, not counting the Coccinelle semantic patch.
> 
>   I think the real question is what's easier to read and to write.  Do
>   you prefer something like
> 
>                     error_report("ISA bus not available for %s", c->name);
>                     exit(1);
> 
>   or something like
> 
>                     error_report_fatal("ISA bus not available for %s",
>                                        c->name);
> 
>   The second form saves a tiny bit of instruction space, I guess.

For this one, actually that's why I wrote this patchset. However, it
does not mean that I think we should have it. I was just trying to
post this out, to see which one we would like better. For me,
error_report() with an exit() is good enough. So, if we are obviously
liking it, I am willing to continue maintain this series until it's
merged. Otherwise, I am still okay to put this series aside if we do
not have a very strong motivation to do the change. :)

Thanks for reviewing!

-- peterx

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-09 17:19   ` Daniel P. Berrange
@ 2016-09-12  8:02     ` Markus Armbruster
  0 siblings, 0 replies; 17+ messages in thread
From: Markus Armbruster @ 2016-09-12  8:02 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: peter.maydell, famz, qemu-devel, Peter Xu, pbonzini

"Daniel P. Berrange" <berrange@redhat.com> writes:

> On Fri, Sep 09, 2016 at 07:05:04PM +0200, Markus Armbruster wrote:
>> Peter Xu <peterx@redhat.com> writes:
>> 
>> > v4 changes:
>> > - remove two standard headers since they are included in osdep.h
>> >   already [Fam]
>> > - make sure it passes build on all platforms (no --target-list
>> >   specified during configure)
>> >
>> > v3 changes:
>> > - implement error_report_fatal using function [Markus]
>> > - provide error_report_abort as well in seperate patch [Markus, Fam]
>> >
>> > We have many use cases that first print some error messages, then
>> > quit (by either exit() or abort()). This series introduce two helper
>> > functions for that.
>> >
>> > The old formats are mostly one of the following:
>> >
>> > Case one:
>> >
>> >   error_report(...);
>> >   exit(1|EXIT_FAILURE) | abort();
>> >
>> > Case two:
>> >
>> >   error_setg(&error_{fatal|abort}, ...);
>> >
>> > And we can convert either of the above cases into:
>> >
>> >   error_report_{fatal|abort}(...);
>> >
>> > Two coccinelle scripts are created to help automate the work, plus
>> > some manual tweaks:
>> >
>> > 1. very long strings, fix for over-80-chars issues, to make sure it
>> >    passes checkpatch.pl.
>> >
>> > 2. add "return XXX" for some non-void retcode functions.
>> >
>> > The first two patches introduce the functions. The latter two apply
>> > them.
>> 
>> You effectively propose to revise this coding rule from error.h:
>> 
>>  * 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().
>> 
>> If we accept your proposal, you get to add a patch to update the rule :)
>> 
>> We've discussed the preferred way to report fatal errors to the human
>> user before.  With actual patches, we can see how a change of rules
>> changes the code.  Do we like the change shown by this patch set?
>> 
>> I believe there are a number of separate issues to discuss here:
>> 
>> * Shall we get rid of error_setg(&error_fatal, ...)?
>> 
>>   This is a no-brainer for me.  Such a simple thing should be done in
>>   one way, not two ways.  I count 14 instances of
>>   error_setg(&error_fatal, ...), but more than 300 of error_report(...);
>>   exit(1).
>
> NB, arguably 99% of the usage of error_setg(&error_fatal) are in
> fact cases where code ought to be eventually converted to accept
> an "Error **errp" parameter and let the caller decide whether to
> exit or not.
>
> IOW, if we take this approach today we'll change
>
>    error_setg(&error_fatal, "....");
>
> into
>
>    error_report_fatal("....");

Or, if we decide we don't want to fuse error_report() and exit(), into

     error_report("....");
     exit(1);

> and then later potentially change it back again to
>
>    error_setg(errp, "....");
>
>
> This isn't the end of the world, but I'm just not convinced that
> the intermediate change to error_report_fatal() buys us anything
> positive overall.

I prefer to get rid of bad examples, even when they're closer to what we
believe the code will look like some day, because bad examples get
copied.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-09 17:05 ` Markus Armbruster
  2016-09-09 17:19   ` Daniel P. Berrange
  2016-09-12  5:33   ` Peter Xu
@ 2016-09-12 19:49   ` Eric Blake
  2016-09-13  6:44     ` Markus Armbruster
  2 siblings, 1 reply; 17+ messages in thread
From: Eric Blake @ 2016-09-12 19:49 UTC (permalink / raw)
  To: Markus Armbruster, Peter Xu; +Cc: peter.maydell, famz, qemu-devel, pbonzini

[-- Attachment #1: Type: text/plain, Size: 4924 bytes --]

On 09/09/2016 12:05 PM, Markus Armbruster wrote:
> 
> You effectively propose to revise this coding rule from error.h:
> 
>  * 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().
> 
> If we accept your proposal, you get to add a patch to update the rule :)
> 
> We've discussed the preferred way to report fatal errors to the human
> user before.  With actual patches, we can see how a change of rules
> changes the code.  Do we like the change shown by this patch set?

That includes diffstats, to help gauge the extent of the change (not as
easy is gauging the ratio of the changed code to the rest of the code
that did not need to change - if we are touching 40% of all callers, it
is invasive because the remaining 60% is not that much more dominant; if
we are touching 2% of all callers it is a great patch for keeping us
consistent with the remaining 98%).

error_report_fatal() had a lot of hits:

 76 files changed, 557 insertions(+), 799 deletions(-)
 create mode 100644 scripts/coccinelle/error_report_fatal.cocci

while error_report_abort() was not as common:

 12 files changed, 41 insertions(+), 32 deletions(-)
 create mode 100644 scripts/coccinelle/error_report_abort.cocci


> 
> I believe there are a number of separate issues to discuss here:
> 
> * Shall we get rid of error_setg(&error_fatal, ...)?
> 
>   This is a no-brainer for me.  Such a simple thing should be done in
>   one way, not two ways.  I count 14 instances of
>   error_setg(&error_fatal, ...), but more than 300 of error_report(...);
>   exit(1).

So this adds some of the percentages that I allude to above: 14/300 is
definitely a case where the outliers are worth making common (so getting
rid of error_setg(&error_fatal) makes sense).  Now, whether we get rid
of the differences by making it all error_setg()/exit() (to match the
300), or whether we change ALL of these to a new error_report_fatal (for
314 changes) is up for a bit more debate:

> 
> * Shall we fuse error_report() and exit() into error_report_fatal()?
> 
>   Saves ~200 lines, not counting the Coccinelle semantic patch.
> 
>   I think the real question is what's easier to read and to write.  Do
>   you prefer something like
> 
>                     error_report("ISA bus not available for %s", c->name);
>                     exit(1);
> 
>   or something like
> 
>                     error_report_fatal("ISA bus not available for %s",
>                                        c->name);
> 
>   The second form saves a tiny bit of instruction space, I guess.

I can live with error_report_fatal().  It makes indentation a bit more
awkward to think about, and hides the fact that it is exit()ing, but if
done commonly enough (and 314 instances in the code base seems
relatively common) along with a Coccinelle script to enforce it, it
seems like it would be a usable idiom.

> 
> * Shall we get rid of error_setg(&error_abort, ...)?
> 
>   Getting rid of it is again a no-brainer, but what to replace it with
>   isn't.
> 
>   In my personal opinion, abort() is a perfectly fine way to handle
>   "this cannot happen" conditions, and printing pretty messages right
>   before abort() is a waste of time.  If the abort() happens, the
>   program is broken, and all the end user needs to know is that he needs
>   to find someone to debug and fix it.  If the end user really needs to
>   know more, use of abort() is usually wrong.
> 
>   But others have different opinions.  If you want to print pretty
>   messages before abort(), you get to print them.
> 
>   The question is whether to provide a fused error_report_abort().  I'd
>   be willing to provide it just for symmetry with error_report_fatal(),
>   if we decide we want error_report_fatal().

I'm leaning towards error_report_abort() as useless, agreeing with the
argument that reporting a nice message before abort()ing is a waste of
time (the ideal program never aborts, so the nice message is either dead
code, or the error is reachable in situations such that you should not
have been trying to abort).  But if we don't convert
error_report_abort(), then having JUST error_report_fatal() as shorthand
on its own merits becomes a bit tougher sell.

I don't know that I have swayed any opinions, so much as just added
commentary to the discussion.  I guess we could easily split this into a
trivial patch (get rid of the 14 error_setg(&error_fatal) via Coccinelle
to error_report()/exit()) as a patch worth applying now, and a second
Coccinelle conversion of error_report()/exit() to error_report_fatal()
as a more ambiguous change of whether we like it or not.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort}
  2016-09-12 19:49   ` Eric Blake
@ 2016-09-13  6:44     ` Markus Armbruster
  0 siblings, 0 replies; 17+ messages in thread
From: Markus Armbruster @ 2016-09-13  6:44 UTC (permalink / raw)
  To: Eric Blake; +Cc: Peter Xu, peter.maydell, famz, qemu-devel, pbonzini

Eric Blake <eblake@redhat.com> writes:

> On 09/09/2016 12:05 PM, Markus Armbruster wrote:
>> 
>> You effectively propose to revise this coding rule from error.h:
>> 
>>  * 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().
>> 
>> If we accept your proposal, you get to add a patch to update the rule :)
>> 
>> We've discussed the preferred way to report fatal errors to the human
>> user before.  With actual patches, we can see how a change of rules
>> changes the code.  Do we like the change shown by this patch set?
>
> That includes diffstats, to help gauge the extent of the change (not as
> easy is gauging the ratio of the changed code to the rest of the code
> that did not need to change - if we are touching 40% of all callers, it
> is invasive because the remaining 60% is not that much more dominant; if
> we are touching 2% of all callers it is a great patch for keeping us
> consistent with the remaining 98%).
>
> error_report_fatal() had a lot of hits:
>
>  76 files changed, 557 insertions(+), 799 deletions(-)
>  create mode 100644 scripts/coccinelle/error_report_fatal.cocci
>
> while error_report_abort() was not as common:
>
>  12 files changed, 41 insertions(+), 32 deletions(-)
>  create mode 100644 scripts/coccinelle/error_report_abort.cocci

I count ~1350 occurences of error_report() in master, a smilar number of
exit(), and ~650 abort().  The series fuses 329 of them into
error_report_fatal(), and 16 into error_report_abort().  Touches roughly
one in four error_report().

Additionally, it normalizes 13 uses of error_setg(&error_fatal, ...) and
2 of error_setg(&error_abort, ...).

>> I believe there are a number of separate issues to discuss here:
>> 
>> * Shall we get rid of error_setg(&error_fatal, ...)?
>> 
>>   This is a no-brainer for me.  Such a simple thing should be done in
>>   one way, not two ways.  I count 14 instances of
>>   error_setg(&error_fatal, ...), but more than 300 of error_report(...);
>>   exit(1).
>
> So this adds some of the percentages that I allude to above: 14/300 is
> definitely a case where the outliers are worth making common (so getting
> rid of error_setg(&error_fatal) makes sense).  Now, whether we get rid
> of the differences by making it all error_setg()/exit() (to match the
> 300), or whether we change ALL of these to a new error_report_fatal (for
> 314 changes) is up for a bit more debate:
>
>> 
>> * Shall we fuse error_report() and exit() into error_report_fatal()?
>> 
>>   Saves ~200 lines, not counting the Coccinelle semantic patch.
>> 
>>   I think the real question is what's easier to read and to write.  Do
>>   you prefer something like
>> 
>>                     error_report("ISA bus not available for %s", c->name);
>>                     exit(1);
>> 
>>   or something like
>> 
>>                     error_report_fatal("ISA bus not available for %s",
>>                                        c->name);
>> 
>>   The second form saves a tiny bit of instruction space, I guess.
>
> I can live with error_report_fatal().  It makes indentation a bit more
> awkward to think about, and hides the fact that it is exit()ing, but if
> done commonly enough (and 314 instances in the code base seems
> relatively common) along with a Coccinelle script to enforce it, it
> seems like it would be a usable idiom.

Roughly 1000 exit() left.

Terminating the program when you shouldn't is a fairly common issue.  To
finding places that do that, you need to grep for functions that do it.
The more we create, the more cumbersome that gets.

This isn't a particularly strong argument against having
error_report_fatal().  However, we need arguments *for* having it :)

>> * Shall we get rid of error_setg(&error_abort, ...)?
>> 
>>   Getting rid of it is again a no-brainer, but what to replace it with
>>   isn't.
>> 
>>   In my personal opinion, abort() is a perfectly fine way to handle
>>   "this cannot happen" conditions, and printing pretty messages right
>>   before abort() is a waste of time.  If the abort() happens, the
>>   program is broken, and all the end user needs to know is that he needs
>>   to find someone to debug and fix it.  If the end user really needs to
>>   know more, use of abort() is usually wrong.
>> 
>>   But others have different opinions.  If you want to print pretty
>>   messages before abort(), you get to print them.
>> 
>>   The question is whether to provide a fused error_report_abort().  I'd
>>   be willing to provide it just for symmetry with error_report_fatal(),
>>   if we decide we want error_report_fatal().
>
> I'm leaning towards error_report_abort() as useless, agreeing with the
> argument that reporting a nice message before abort()ing is a waste of
> time (the ideal program never aborts, so the nice message is either dead
> code, or the error is reachable in situations such that you should not
> have been trying to abort).  But if we don't convert
> error_report_abort(), then having JUST error_report_fatal() as shorthand
> on its own merits becomes a bit tougher sell.

Yes.

> I don't know that I have swayed any opinions, so much as just added
> commentary to the discussion.  I guess we could easily split this into a
> trivial patch (get rid of the 14 error_setg(&error_fatal) via Coccinelle
> to error_report()/exit()) as a patch worth applying now, and a second
> Coccinelle conversion of error_report()/exit() to error_report_fatal()
> as a more ambiguous change of whether we like it or not.

Yes, split this into the uncontroversial part getting rid of the
error_setg() usage that goes against the comment in error.h, and the
part we're not sure about.

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2016-09-13  6:44 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-07  6:06 [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Peter Xu
2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 1/4] error-report: provide error_report_fatal() Peter Xu
2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 2/4] error-report: provide error_report_abort() Peter Xu
2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 3/4] error-report: leverage error_report_fatal() Peter Xu
2016-09-07  6:06 ` [Qemu-devel] [PATCH v4 4/4] error-report: leverage error_report_abort() Peter Xu
2016-09-07  6:39 ` [Qemu-devel] [PATCH v4 0/4] Introduce error_report_{fatal|abort} Fam Zheng
2016-09-07  9:23 ` Alex Bennée
2016-09-07  9:33   ` Fam Zheng
2016-09-07 10:42     ` Peter Xu
2016-09-07 12:39     ` Lluís Vilanova
2016-09-07 13:48       ` Markus Armbruster
2016-09-09 17:05 ` Markus Armbruster
2016-09-09 17:19   ` Daniel P. Berrange
2016-09-12  8:02     ` Markus Armbruster
2016-09-12  5:33   ` Peter Xu
2016-09-12 19:49   ` Eric Blake
2016-09-13  6:44     ` Markus Armbruster

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.