utils: Improve and document error reporting
v6 cover utils: Improve and document error reporting
Adds leaner error-reporting functions for simple cases, and documents the purpose of the different facilities available in QEMU.
Although not all printf+exit/abort are replaced with the proper functions, a few are ported as an example.
Changes in v6
=============
* Rebase on 074d1cc [David Gibson].
* Fix typo in documentation [Eric Blake].
* Clarify when to use fatal/abort [Eric Blake].
Changes in v5
=============
* Fix typo in documentation [Eric Blake].
Changes in v4
=============
* Introduce 'error_report_fatal()' and 'error_report_abort()' functions [suggested by Thomas Huth].
* Repalce all existing uses of 'error_setg(error_fatal)' and 'error_setg(error_abort)' with 'error_report_fatal()' and 'error_report_abort()'.
* Replace all uses of 'exit()' with 'error_report_fatal()' in 'target-ppc'.
* Replace all uses of 'abort()' with 'error_report_abort()' in 'target-ppc'.
Changes in v3
=============
* Drop special object 'error_warn' in favour of raw 'error_report()' [suggested by Markus Armbruster].
Changes in v2
=============
* Split in two patches.
* Explicitly add a warning error object.
---
Lluís Vilanova (5):
util: Introduce error reporting functions with fatal/abort
util: Use new error_report_fatal/abort instead of error_setg(&error_fatal/abort)
util: [ppc] Use new error_report_fatal() instead of exit()
util: [ppc] Use new error_report_abort() instead of abort()
doc: Introduce coding style for errors
HACKING | 37 ++++++++++++++++++++ hw/block/fdc.c | 6 ++- hw/ppc/spapr.c | 8 ++-- hw/ppc/spapr_drc.c | 2 + include/qemu/error-report.h | 19 ++++++++++ target-ppc/kvm.c | 9 ++--- target-ppc/kvm_ppc.h | 15 +++++--- target-ppc/mmu-hash32.c | 5 ++- target-ppc/mmu_helper.c | 3 +- target-ppc/translate.c | 7 ++-- target-ppc/translate_init.c | 80 +++++++++++++++++++++---------------------- util/error.c | 9 ++--- util/qemu-error.c | 33 ++++++++++++++++++ 13 files changed, 159 insertions(+), 74 deletions(-)
To: [email protected]
Cc: David Gibson <[email protected]>
Cc: Stefan Hajnoczi <[email protected]>
Cc: Dr. David Alan Gilbert <[email protected]>
Cc: Thomas Huth <[email protected]>
Cc: Markus Armbruster <[email protected]>
Cc: Eric Blake <[email protected]>
PATCH v6 1/5 util: Introduce error reporting functions with fatal/abort
Provide two lean functions to report error messages that fatal/abort QEMU.
--- include/qemu/error-report.h | 19 +++++++++++++++++++ util/qemu-error.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)
include/qemu/error-report.h +19 -0
@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +/* Report message with caller location and abort */ +#define error_vreport_abort (fmt, ap) \ + do { \ + error_report_abort_caller_internal(__FILE__, __LINE__, __func__); \ + error_vreport_abort_internal(fmt, ap); \ + } while (0) +#define error_report_abort (fmt, ...) \ + do { \ + error_report_abort_caller_internal(__FILE__, __LINE__, __func__); \ + error_report_abort_internal(fmt, ##__VA_ARGS__); \ + } while (0) + +void error_report_abort_caller_internal (const char *file,int line,const char *func); +void QEMU_NORETURN error_vreport_abort_internal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_abort_internal(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +#endif
util/qemu-error.c +33 -0
@@ -237,3 +237,36 @@ void error_report(const char *fmt, ...)error_vreport (fmt, ap);va_end (ap); } + +void error_vreport_fatal (const char *fmt,va_list ap) +{ +error_vreport (fmt, ap); +exit (1 ); +} + +void error_report_fatal (const char *fmt, ...) +{ +va_list ap; +va_start (ap, fmt); +error_vreport_fatal (fmt, ap); +va_end (ap); +} + +void error_report_abort_caller_internal (const char *file,int line,const char *func) +{ +error_report ("Unexpected error in %s() at %s:%d:" , func, file, line); +} + +void error_vreport_abort_internal (const char *fmt,va_list ap) +{ +error_vreport (fmt, ap); +abort (); +} + +void error_report_abort_internal (const char *fmt, ...) +{ +va_list ap; +va_start (ap, fmt); +error_vreport_abort_internal (fmt, ap); +va_end (ap); +}
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
I'm struggling with my review queue, and have had to resort to subsystem batching to increase throughput. Because of that, v3-v5 have flown by without a peep from me. My sincere apologies.
Quoted 14 lines · Lluís Vilanova
Provide two lean functions to report error messages that fatal/abort QEMU.
Signed-off-by Lluís Vilanova <[email protected]>--- include/qemu/error-report.h | 19 +++++++++++++++++++ util/qemu-error.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)include/qemu/error-report.h +0
-0
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 6 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling");
exit(1);or
fprintf(stderr, "The sky is falling\n");
exit(1);I don't think that's an improvement in clarity.
PATCH 3 actually does this for a couple of cases.
Quoted 7 lines
include/qemu/error-report.h +7
-0+/* Report message with caller location and abort */ +#define error_vreport_abort (fmt, ap) \ + do { \ + error_report_abort_caller_internal(__FILE__, __LINE__, __func__); \ + error_vreport_abort_internal(fmt, ap); \ + } while (0) +#define error_report_abort (fmt, ...) \
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 65
Quoted 10 lines
include/qemu/error-report.h +9
-0+do { \ +error_report_abort_caller_internal (__FILE__, __LINE__, __func__); \ + error_report_abort_internal(fmt, ##__VA_ARGS__); \ + } while (0) + +void error_report_abort_caller_internal (const char *file,int line,const char *func); +void QEMU_NORETURN error_vreport_abort_internal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_abort_internal(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +#endif
Feature not mentioned in the commit message: your new form prints an additional line with source location information, like &error_abort does. See error_report_abort_internal() below.
PATCH 4 uses error_report_abort() to change a dozen
abort()
to
error_report_abort(... some message ...);
or even
error_report_abort(" ");Two aspects: source code and behavior.
Source code: I don't think it makes it more readable.
Behavior: prints a message before it crashes.
The messages look like they make sense only to developers, not to users. This isn't surprising; these are internal errors, and you generally can't explain internal errors without referring to internal concepts the user doesn't know about. Should they happen, you need to debug anyway.
As to the " " messages: surely you're joking, Mr. Feynman :)
I feel the message adds very little information to the core dump for developers, and none for users.
If the error message is genuinely useful to users, chances are we should exit(1) rather than abort().
If the QEMU developer community should decide I'm wrong and we really want to decorate abort()s with messages, we'd have to decorate the majority of the 600+ we have so that people can see the pattern. Without that, new undecorated ones will pop up faster than we can decorate them. In other words, the dozen you converted to demonstrate the idea for your RFC are a placeholder for one of these tree-wide transitions that are easier to start than to finish.
PATCH 2 uses error_report_abort() to clean up
error_setg(&error_abort, ... some message ...);
to
error_report_abort(... some message ...);
I agree these uses of &error_abort should be cleaned up. However, I'd clean them up to abort() or assert(), for the reasons I just explained, and because that's what we do elsewhere.
Quoted 16 lines
util/qemu-error.c +8
-0@@ -237,3 +237,36 @@ void error_report(const char *fmt, ...)error_vreport (fmt, ap);va_end (ap); } + +void error_vreport_fatal (const char *fmt,va_list ap) +{ +error_vreport (fmt, ap); +exit (1 ); +} + +void error_report_fatal (const char *fmt, ...)
util/qemu-error.c void error_report(const char *fmt, ...) · line 257
Quoted 10 lines
util/qemu-error.c +10
-0+{ +va_list ap; +va_start (ap, fmt); +error_vreport_fatal (fmt, ap); +va_end (ap); +} + +void error_report_abort_caller_internal (const char *file,int line,const char *func) +{ +error_report ("Unexpected error in %s() at %s:%d:" , func, file, line);
Should use error_printf(), so we get
Unexpected error in frobnicate() at frob.c:666:
qemu-system-x86_64: --frobnicate: Out of frobs
instead of
qemu-system-x86_64: --frobnicate: Unexpected error in frobnicate() at frob.c:666:
qemu-system-x86_64: --frobnicate: Out of frobs
Quoted 15 lines
util/qemu-error.c +15
-0+} + +void error_vreport_abort_internal (const char *fmt,va_list ap) +{ +error_vreport (fmt, ap); +abort (); +} + +void error_report_abort_internal (const char *fmt, ...) +{ +va_list ap; +va_start (ap, fmt); +error_vreport_abort_internal (fmt, ap); +va_end (ap); +}
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 21 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling"); exit(1);
Quoted 6 lines
or
fprintf(stderr, "The sky is falling\n"); exit(1);I don't think that's an improvement in clarity.
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );
to do error reporting - which is IMHO the most ugliest way to do this, because I'd really not expect error_setg() to (always) exit QEMU when I quickly read through the sources.
We fortunately do not have that in the sources yet (only some few spots with error_abort), but to prevent that people start using that, it would be good to have a error_report_fatal() function instead, I think.
Alternatively, if you really want to see the exit(1) in the sources, I think this should be mentioned in the coding guidelines ... or are you fine with error_setg(&error_fatal, ...), Markus?
Thomas
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 30 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 26 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling"); exit(1);or
fprintf(stderr, "The sky is falling\n"); exit(1);
Quoted 6 lines
Quoted 1 line
I don't think that's an improvement in clarity.
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );
So, I don't actually see any real advantage to error_report_fatal(...) over error_setg(&error_fatal, ...).
Quoted 13 lines
to do error reporting - which is IMHO the most ugliest way to do this, because I'd really not expect
error_setg()to (always) exit QEMU when I quickly read through the sources.
We fortunately do not have that in the sources yet (only some few spots witherror_abort), but to prevent that people start using that, it would be good to have aerror_report_fatal()function instead, I think.Alternatively, if you really want to see the exit(1) in the sources, I think this should be mentioned in the coding guidelines ... or are you fine with
error_setg(&error_fatal, ...), Markus?Thomas
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling"); exit(1);or
fprintf(stderr, "The sky is falling\n"); exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).
I do. Compare:
(a) error_report(...);
exit(1);(b) error_report_fatal(...);
(c) error_setg(&error_fatal, ...);
In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what error_report() approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.
Let's stick to the obvious (a) and be done with it.
[...]
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 50 lines · Markus Armbruster
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling"); exit(1);or
fprintf(stderr, "The sky is falling\n"); exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).I do. Compare:
(a) error_report(...); exit(1);(b)
error_report_fatal(...);
Quoted 8 lines
(c)
error_setg(&error_fatal, ...);In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what
error_report()approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.Let's stick to the obvious (a) and be done with it.
Ok, (a) is fine for me too, as long as we avoid (c). Lluís, could you maybe add that information to your patch that updates the HACKING text? (and sorry for the fuzz with error_report_fatal() ... I thought it would be a good solution to avoid (c), but if (a) is preferred instead, then we should go with that solution instead).
And, by the way, what about the spots that currently already use error_setg(&error_abort, ....) ? Should they be turned into error_report() + abort() instead? Or only abort(), without error message, since abort() is only about programming errors?
Thomas
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 58 lines · Thomas Huth
Quoted 57 lines · Markus Armbruster
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling"); exit(1);or
fprintf(stderr, "The sky is falling\n"); exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).I do. Compare:
(a) error_report(...); exit(1);(b)
error_report_fatal(...);(c)
error_setg(&error_fatal, ...);In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what
error_report()approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.
Quoted 4 lines
Quoted 1 line
Let's stick to the obvious (a) and be done with it.
Ok, (a) is fine for me too, as long as we avoid (c). Lluís, could you maybe add that information to your patch that updates the HACKING text?
I feel such detailed advice belings into error.h. Sketch appended.
If that doesn't succeed in keeping (c) out, make checkpatch flag it.
Quoted 8 lines
(and sorry for the fuzz with
error_report_fatal()... I thought it would be a good solution to avoid (c), but if (a) is preferred instead, then we should go with that solution instead).And, by the way, what about the spots that currently already use
error_setg(&error_abort, ....)? Should they be turned intoerror_report()+abort()instead? Or onlyabort(), without error message, sinceabort()is only about programming errors?
As I wrote in my first reply to this thread, I'd like them to be cleaned up to just abort() or assert().
I like assert(), because it gives me exactly what I can use to debug the programming error: a core dump (if enabled) and a source location (useful when no core dump). I never bought the argument that we should use abort() instead of assert(0) because "what if NDEBUG?!?". If you define NDEBUG, our 600+ abort()s won't save you from our 4000+ assert()s.
include/qapi/error.h +9 -2
@@ -162,6 +162,9 @@ ErrorClass error_get_class(const Error *err);* human-readable error message is made from printf-style @fmt, ... * The resulting message should be a single phrase, with no newline or * trailing punctuation. +* Please don't error_setg(&error_fatal, ...), use error_report() and +* exit(), because that's more obvious. +* Likewise, don't error_setg(&error_abort, ...), use assert(). */ #define error_setg (errp, fmt, ...) \ error_setg_internal((errp), __FILE__, __LINE__, __func__, \
@@ -213,6 +216,8 @@ void error_setg_win32_internal(Error **errp,* the error object. * Else, move the error object from @local_err to *@dst_errp. * On return, @local_err is invalid. +* Please don't error_propagate(&error_fatal, ...), use +* error_report_err() and exit(), because that's more obvious. */ void error_propagate (Error **dst_errp,Error *local_err);
@@ -291,12 +296,14 @@ void error_set_internal(Error **errp,GCC_FMT_ATTR (6 ,7 );/* -* Pass to error_setg() & friends to abort() on error. +* Special error destination to abort on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_abort;/* -* Pass to error_setg() & friends to exit(1) on error. +* Special error destination to exit(1) on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_fatal;
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 59 lines · Markus Armbruster
Quoted 58 lines · Thomas Huth
Quoted 57 lines · Markus Armbruster
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling");
exit(1);or
fprintf(stderr, "The sky is falling\n");
exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );
So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).I do. Compare:
(a)
error_report(...);
exit(1);(b)
error_report_fatal(...);(c)
error_setg(&error_fatal, ...);In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what
error_report()approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.
Quoted 12 lines
Quoted 4 lines
Quoted 1 line
Let's stick to the obvious (a) and be done with it.
Ok, (a) is fine for me too, as long as we avoid (c). Lluís, could you maybe add that information to your patch that updates the HACKING text?
I feel such detailed advice belings into
error.h. Sketch appended.If that doesn't succeed in keeping (c) out, make checkpatch flag it.
Quoted 3 lines
(and sorry for the fuzz with
error_report_fatal()... I thought it would be a good solution to avoid (c), but if (a) is preferred instead, then we should go with that solution instead).
I can easily change that, no problem. I'm just happy consensus is landing on this subject.
Quoted 8 lines
Quoted 4 lines
And, by the way, what about the spots that currently already use
error_setg(&error_abort, ....)? Should they be turned intoerror_report()+abort()instead? Or onlyabort(), without error message, sinceabort()is only about programming errors?As I wrote in my first reply to this thread, I'd like them to be cleaned up to just
abort()orassert().
Quoted 6 lines
I like
assert(), because it gives me exactly what I can use to debug the programming error: a core dump (if enabled) and a source location (useful when no core dump). I never bought the argument that we should useabort()instead of assert(0) because "what if NDEBUG?!?". If you define NDEBUG, our 600+ abort()s won't save you from our 4000+ assert()s.
Sorry, but I don't buy the argument of, "I prefer assert() because there's already lots of them". To me, there's a semantic difference between debug builds and regular ones (aka, assert vs abort). Also, I think it adds to the confusion that assert and abort seem to be used interchangeably in the code.
What about this definition?
* exit(): user-triggered errors
* abort(): general programming errors
* assert(): additional sanity/consistency checks against programming errors
Now, abort & assert have an overlap. Should we discourage one in favour of the other?
Also:
* error_report_fatal ensures the same exit code is always used (otherwise it can fail with inconsistent error codes)
* error_report_abort brings the code information of assert into abort
But of course, I'm happy either way :)
Quoted 29 lines
include/qapi/error.h +6
-1@@ -162,6 +162,9 @@ ErrorClass error_get_class(const Error *err);* human-readable error message is made from printf-style @fmt, ... * The resulting message should be a single phrase, with no newline or * trailing punctuation. +* Please don't error_setg(&error_fatal, ...), use error_report() and +* exit(), because that's more obvious. +* Likewise, don't error_setg(&error_abort, ...), use assert(). */ #define error_setg (errp, fmt, ...) \ error_setg_internal((errp), __FILE__, __LINE__, __func__, \@@ -213,6 +216,8 @@ void error_setg_win32_internal(Error **errp,* the error object. * Else, move the error object from @local_err to *@dst_errp. * On return, @local_err is invalid. +* Please don't error_propagate(&error_fatal, ...), use +* error_report_err() and exit(), because that's more obvious. */ void error_propagate (Error **dst_errp,Error *local_err);@@ -291,12 +296,14 @@ void error_set_internal(Error **errp,GCC_FMT_ATTR (6 ,7 );/* -* Pass to error_setg() & friends to abort() on error. +* Special error destination to abort on error.
include/qapi/error.h void error_set_internal(Error **errp, · line 308
Quoted 10 lines
include/qapi/error.h +3
-1+* See error_setg() and error_propagate() for details. */ extern Error *error_abort;/* -* Pass to error_setg() & friends to exit(1) on error. +* Special error destination to exit(1) on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_fatal;
I see, this will make it clearer for people looking for functions without reading HACKING. I can add this and reference it from the document.
Thanks,
Lluis
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 93 lines · Lluís Vilanova
Quoted 59 lines · Markus Armbruster
Quoted 58 lines · Thomas Huth
Quoted 57 lines · Markus Armbruster
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling");
exit(1);or
fprintf(stderr, "The sky is falling\n");
exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );
So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).I do. Compare:
(a)
error_report(...);
exit(1);(b)
error_report_fatal(...);(c)
error_setg(&error_fatal, ...);In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what
error_report()approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.Quoted 12 lines
Quoted 4 lines
Quoted 1 line
Let's stick to the obvious (a) and be done with it.
Ok, (a) is fine for me too, as long as we avoid (c). Lluís, could you maybe add that information to your patch that updates the HACKING text?
I feel such detailed advice belings into
error.h. Sketch appended.If that doesn't succeed in keeping (c) out, make checkpatch flag it.
Quoted 3 lines
(and sorry for the fuzz with
error_report_fatal()... I thought it would be a good solution to avoid (c), but if (a) is preferred instead, then we should go with that solution instead).I can easily change that, no problem. I'm just happy consensus is landing on this subject.
Quoted 8 lines
Quoted 4 lines
And, by the way, what about the spots that currently already use
error_setg(&error_abort, ....)? Should they be turned intoerror_report()+abort()instead? Or onlyabort(), without error message, sinceabort()is only about programming errors?As I wrote in my first reply to this thread, I'd like them to be cleaned up to just
abort()orassert().Quoted 6 lines
I like
assert(), because it gives me exactly what I can use to debug the programming error: a core dump (if enabled) and a source location (useful when no core dump). I never bought the argument that we should useabort()instead of assert(0) because "what if NDEBUG?!?". If you define NDEBUG, our 600+ abort()s won't save you from our 4000+ assert()s.
Quoted 3 lines
Sorry, but I don't buy the argument of, "I prefer
assert()because there's already lots of them". To me, there's a semantic difference between debug builds and regular ones (aka, assert vs abort).
That's not what I said :)
In the past, people have argued in favor of abort() by pointing to NDEBUG. I don't buy that argument, but me not buying it is not why I prefer assert(). I do because it prints additional information that's occasionally useful.
Quoted 2 lines
Also, I think it adds to the confusion
that assert and abort seem to be used interchangeably in the code.
For better or worse, we overwhelmingly use abort() instead of assert(0), but don't use if (!good) abort() instead of assert(good). Doesn't make sense to me, but my appetite for tree-wide changes and the debates that go with them has limits.
Quoted 8 lines
What about this definition?
*
exit(): user-triggered errors
*abort(): general programming errors
*assert(): additional sanity/consistency checks against programming errorsNow, abort & assert have an overlap. Should we discourage one in favour of the other?
I can't see how to decide whether a programming error is "general" or "additional", or why an "additional" one error deserves a message pointing to source code, but a "general" one does not.
Quoted 4 lines
Also:
*
error_report_fatalensures the same exit code is always used (otherwise it can fail with inconsistent error codes)
What if you *want* to use a different exit code?
But I grant you that we should almost always use exit(1) for fatal errors. And in fact we do! There are a bunch of misguided exit(-1) in the code, but git-log -S'exit(-1)' finds only half a dozen offending commits since 2013, and none since 2015, so preventing more seems to be a mostly solved problem.
Quoted 1 line
*
error_report_abortbrings the code information of assert into abort
If you want your crashes to print source location information, don't reinvent the wheel, just use assert().
&error_abort can't because the interesting spot isn't where we decide to abort, but where the error got created.
Quoted 43 lines
But of course, I'm happy either way :)
Quoted 29 lines
include/qapi/error.h +6
-1@@ -162,6 +162,9 @@ ErrorClass error_get_class(const Error *err);* human-readable error message is made from printf-style @fmt, ... * The resulting message should be a single phrase, with no newline or * trailing punctuation. +* Please don't error_setg(&error_fatal, ...), use error_report() and +* exit(), because that's more obvious. +* Likewise, don't error_setg(&error_abort, ...), use assert(). */ #define error_setg (errp, fmt, ...) \ error_setg_internal((errp), __FILE__, __LINE__, __func__, \@@ -213,6 +216,8 @@ void error_setg_win32_internal(Error **errp,* the error object. * Else, move the error object from @local_err to *@dst_errp. * On return, @local_err is invalid. +* Please don't error_propagate(&error_fatal, ...), use +* error_report_err() and exit(), because that's more obvious. */ void error_propagate (Error **dst_errp,Error *local_err);@@ -291,12 +296,14 @@ void error_set_internal(Error **errp,GCC_FMT_ATTR (6 ,7 );/* -* Pass to error_setg() & friends to abort() on error. +* Special error destination to abort on error. include/qapi/error.h void error_set_internal(Error **errp, · line 308
Quoted 10 lines
include/qapi/error.h +3
-1+* See error_setg() and error_propagate() for details. */ extern Error *error_abort;/* -* Pass to error_setg() & friends to exit(1) on error. +* Special error destination to exit(1) on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_fatal;
Quoted 2 lines
I see, this will make it clearer for people looking for functions without reading HACKING. I can add this and reference it from the document.
If you like, I can post it as a formal patch you can then include in your series.
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 139 lines · Markus Armbruster
Quoted 93 lines · Lluís Vilanova
Quoted 59 lines · Markus Armbruster
Quoted 58 lines · Thomas Huth
Quoted 57 lines · Markus Armbruster
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling");
exit(1);or
fprintf(stderr, "The sky is falling\n");
exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );
So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).I do. Compare:
(a)
error_report(...);
exit(1);(b)
error_report_fatal(...);(c)
error_setg(&error_fatal, ...);In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what
error_report()approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.Quoted 12 lines
Quoted 4 lines
Quoted 1 line
Let's stick to the obvious (a) and be done with it.
Ok, (a) is fine for me too, as long as we avoid (c). Lluís, could you maybe add that information to your patch that updates the HACKING text?
I feel such detailed advice belings into
error.h. Sketch appended.If that doesn't succeed in keeping (c) out, make checkpatch flag it.
Quoted 3 lines
(and sorry for the fuzz with
error_report_fatal()... I thought it would be a good solution to avoid (c), but if (a) is preferred instead, then we should go with that solution instead).I can easily change that, no problem. I'm just happy consensus is landing on this subject.
Quoted 8 lines
Quoted 4 lines
And, by the way, what about the spots that currently already use
error_setg(&error_abort, ....)? Should they be turned intoerror_report()+abort()instead? Or onlyabort(), without error message, sinceabort()is only about programming errors?As I wrote in my first reply to this thread, I'd like them to be cleaned up to just
abort()orassert().Quoted 6 lines
I like
assert(), because it gives me exactly what I can use to debug the programming error: a core dump (if enabled) and a source location (useful when no core dump). I never bought the argument that we should useabort()instead of assert(0) because "what if NDEBUG?!?". If you define NDEBUG, our 600+ abort()s won't save you from our 4000+ assert()s.Quoted 3 lines
Sorry, but I don't buy the argument of, "I prefer
assert()because there's already lots of them". To me, there's a semantic difference between debug builds and regular ones (aka, assert vs abort).That's not what I said :)
In the past, people have argued in favor of
abort()by pointing to NDEBUG. I don't buy that argument, but me not buying it is not why I preferassert(). I do because it prints additional information that's occasionally useful.Quoted 2 lines
Also, I think it adds to the confusion
that assert and abort seem to be used interchangeably in the code.For better or worse, we overwhelmingly use
abort()instead of assert(0), but don't use if (!good)abort()instead of assert(good). Doesn't make sense to me, but my appetite for tree-wide changes and the debates that go with them has limits.Quoted 8 lines
What about this definition?
*
exit(): user-triggered errors
*abort(): general programming errors
*assert(): additional sanity/consistency checks against programming errorsNow, abort & assert have an overlap. Should we discourage one in favour of the other?
I can't see how to decide whether a programming error is "general" or "additional", or why an "additional" one error deserves a message pointing to source code, but a "general" one does not.
Quoted 4 lines
Also:
*
error_report_fatalensures the same exit code is always used (otherwise it can fail with inconsistent error codes)What if you *want* to use a different exit code?
But I grant you that we should almost always use exit(1) for fatal errors. And in fact we do! There are a bunch of misguided exit(-1) in the code, but git-log -S'exit(-1)' finds only half a dozen offending commits since 2013, and none since 2015, so preventing more seems to be a mostly solved problem.
Quoted 7 lines
Quoted 1 line
*
error_report_abortbrings the code information of assert into abortIf you want your crashes to print source location information, don't reinvent the wheel, just use
assert().
&error_abortcan't because the interesting spot isn't where we decide to abort, but where the error got created.
Fair enough. I don't want a flame on style either, although I might look like wanting one :)
Quoted 43 lines
Quoted 43 lines
But of course, I'm happy either way :)
Quoted 39 lines
include/qapi/error.h +9
-2@@ -162,6 +162,9 @@ ErrorClass error_get_class(const Error *err);* human-readable error message is made from printf-style @fmt, ... * The resulting message should be a single phrase, with no newline or * trailing punctuation. +* Please don't error_setg(&error_fatal, ...), use error_report() and +* exit(), because that's more obvious. +* Likewise, don't error_setg(&error_abort, ...), use assert(). */ #define error_setg (errp, fmt, ...) \ error_setg_internal((errp), __FILE__, __LINE__, __func__, \@@ -213,6 +216,8 @@ void error_setg_win32_internal(Error **errp,* the error object. * Else, move the error object from @local_err to *@dst_errp. * On return, @local_err is invalid. +* Please don't error_propagate(&error_fatal, ...), use +* error_report_err() and exit(), because that's more obvious. */ void error_propagate (Error **dst_errp,Error *local_err);@@ -291,12 +296,14 @@ void error_set_internal(Error **errp,GCC_FMT_ATTR (6 ,7 );/* -* Pass to error_setg() & friends to abort() on error. +* Special error destination to abort on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_abort;/* -* Pass to error_setg() & friends to exit(1) on error. +* Special error destination to exit(1) on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_fatal;
Quoted 5 lines
Quoted 2 lines
I see, this will make it clearer for people looking for functions without reading HACKING. I can add this and reference it from the document.
If you like, I can post it as a formal patch you can then include in your series.
That'd be great. Please cc me when you send it.
Thanks,
Lluis
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
Quoted 143 lines · Lluís Vilanova
Quoted 140 lines · Markus Armbruster
Quoted 93 lines · Lluís Vilanova
Quoted 59 lines · Markus Armbruster
Quoted 58 lines · Thomas Huth
Quoted 57 lines · Markus Armbruster
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling");
exit(1);or
fprintf(stderr, "The sky is falling\n");
exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );
So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).I do. Compare:
(a)
error_report(...);
exit(1);(b)
error_report_fatal(...);(c)
error_setg(&error_fatal, ...);In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what
error_report()approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.Quoted 12 lines
Quoted 4 lines
Quoted 1 line
Let's stick to the obvious (a) and be done with it.
Ok, (a) is fine for me too, as long as we avoid (c). Lluís, could you maybe add that information to your patch that updates the HACKING text?
I feel such detailed advice belings into
error.h. Sketch appended.If that doesn't succeed in keeping (c) out, make checkpatch flag it.
Quoted 3 lines
(and sorry for the fuzz with
error_report_fatal()... I thought it would be a good solution to avoid (c), but if (a) is preferred instead, then we should go with that solution instead).I can easily change that, no problem. I'm just happy consensus is landing on this subject.
Quoted 8 lines
Quoted 4 lines
And, by the way, what about the spots that currently already use
error_setg(&error_abort, ....)? Should they be turned intoerror_report()+abort()instead? Or onlyabort(), without error message, sinceabort()is only about programming errors?As I wrote in my first reply to this thread, I'd like them to be cleaned up to just
abort()orassert().Quoted 6 lines
I like
assert(), because it gives me exactly what I can use to debug the programming error: a core dump (if enabled) and a source location (useful when no core dump). I never bought the argument that we should useabort()instead of assert(0) because "what if NDEBUG?!?". If you define NDEBUG, our 600+ abort()s won't save you from our 4000+ assert()s.Quoted 3 lines
Sorry, but I don't buy the argument of, "I prefer
assert()because there's already lots of them". To me, there's a semantic difference between debug builds and regular ones (aka, assert vs abort).That's not what I said :)
In the past, people have argued in favor of
abort()by pointing to NDEBUG. I don't buy that argument, but me not buying it is not why I preferassert(). I do because it prints additional information that's occasionally useful.Quoted 2 lines
Also, I think it adds to the confusion
that assert and abort seem to be used interchangeably in the code.For better or worse, we overwhelmingly use
abort()instead of assert(0), but don't use if (!good)abort()instead of assert(good). Doesn't make sense to me, but my appetite for tree-wide changes and the debates that go with them has limits.Quoted 8 lines
What about this definition?
*
exit(): user-triggered errors
*abort(): general programming errors
*assert(): additional sanity/consistency checks against programming errorsNow, abort & assert have an overlap. Should we discourage one in favour of the other?
I can't see how to decide whether a programming error is "general" or "additional", or why an "additional" one error deserves a message pointing to source code, but a "general" one does not.
Quoted 4 lines
Also:
*
error_report_fatalensures the same exit code is always used (otherwise it can fail with inconsistent error codes)What if you *want* to use a different exit code?
But I grant you that we should almost always use exit(1) for fatal errors. And in fact we do! There are a bunch of misguided exit(-1) in the code, but git-log -S'exit(-1)' finds only half a dozen offending commits since 2013, and none since 2015, so preventing more seems to be a mostly solved problem.
Quoted 1 line
*
error_report_abortbrings the code information of assert into abort
Quoted 8 lines
Quoted 5 lines
If you want your crashes to print source location information, don't reinvent the wheel, just use
assert().
&error_abortcan't because the interesting spot isn't where we decide to abort, but where the error got created.Fair enough. I don't want a flame on style either, although I might look like wanting one :)
I think we're having a civil, constructive discussion on error handling and reporting that happens to include stylistic aspects :)
Quoted 43 lines
Quoted 43 lines
Quoted 43 lines
But of course, I'm happy either way :)
Quoted 39 lines
include/qapi/error.h +9
-2@@ -162,6 +162,9 @@ ErrorClass error_get_class(const Error *err);* human-readable error message is made from printf-style @fmt, ... * The resulting message should be a single phrase, with no newline or * trailing punctuation. +* Please don't error_setg(&error_fatal, ...), use error_report() and +* exit(), because that's more obvious. +* Likewise, don't error_setg(&error_abort, ...), use assert(). */ #define error_setg (errp, fmt, ...) \ error_setg_internal((errp), __FILE__, __LINE__, __func__, \@@ -213,6 +216,8 @@ void error_setg_win32_internal(Error **errp,* the error object. * Else, move the error object from @local_err to *@dst_errp. * On return, @local_err is invalid. +* Please don't error_propagate(&error_fatal, ...), use +* error_report_err() and exit(), because that's more obvious. */ void error_propagate (Error **dst_errp,Error *local_err);@@ -291,12 +296,14 @@ void error_set_internal(Error **errp,GCC_FMT_ATTR (6 ,7 );/* -* Pass to error_setg() & friends to abort() on error. +* Special error destination to abort on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_abort;/* -* Pass to error_setg() & friends to exit(1) on error. +* Special error destination to exit(1) on error. +* See error_setg() and error_propagate() for details. */ extern Error *error_fatal;
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I see, this will make it clearer for people looking for functions without reading HACKING. I can add this and reference it from the document.
If you like, I can post it as a formal patch you can then include in your series.
That'd be great. Please cc me when you send it.
Done: [PATCH 0/2] error: Documentation updates
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
In reply to Markus ArmbrusterQuoted 50 lines · Markus Armbruster
Quoted 33 lines · David Gibson
Quoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 27 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling"); exit(1);or
fprintf(stderr, "The sky is falling\n"); exit(1);I don't think that's an improvement in clarity.
Quoted 7 lines
Quoted 4 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );So, I don't actually see any real advantage to
error_report_fatal(...)overerror_setg(&error_fatal, ...).I do. Compare:
(a) error_report(...); exit(1);(b)
error_report_fatal(...);
Quoted 8 lines
(c)
error_setg(&error_fatal, ...);In my opinion, (a) is clearest: even a relatively clueless reader will know what exit(1) does, can guess what
error_report()approximately does, and doesn't need to know what it does exactly. (b) is slightly less obvious, and (c) is positively opaque.Let's stick to the obvious (a) and be done with it.
I'm fine with that, but I still see no real difference between (b) and (c).
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
In reply to Thomas HuthQuoted 32 lines · Thomas Huth
Quoted 1 line · Markus Armbruster
Lluís Vilanova <[email protected]> writes:
...
Quoted 21 lines
include/qemu/error-report.h void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); · line 48
Quoted 11 lines
include/qemu/error-report.h +3
-0@@ -43,4 +43,23 @@ void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);const char *error_get_progname (void );extern bool enable_timestamp_msg; +/* Report message and exit with error */ +void QEMU_NORETURN error_vreport_fatal(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); +void QEMU_NORETURN error_report_fatal(const char *fmt, ...) GCC_FMT_ATTR(1, 2);This lets people write things like
error_report_fatal("The sky is falling");instead of
error_report("The sky is falling"); exit(1);Quoted 6 lines
or
fprintf(stderr, "The sky is falling\n"); exit(1);I don't think that's an improvement in clarity.
Quoted 8 lines
The problem is not the existing code, but that in a couple of new patches, I've now already seen that people are trying to use
error_setg(&error_fatal, ... );to do error reporting - which is IMHO the most ugliest way to do this, because I'd really not expect
error_setg()to (always) exit QEMU when I quickly read through the sources.
I agree that this pattern is not wanted.
Quoted 3 lines
We fortunately do not have that in the sources yet (only some few spots with
error_abort), but to prevent that people start using that, it would be good to have aerror_report_fatal()function instead, I think.
I doubt an error_report_fatal() function would be much better at stopping this pattern than the existing error_report(); exit(1) is.
Quoted 3 lines
Alternatively, if you really want to see the exit(1) in the sources, I think this should be mentioned in the coding guidelines ... or are you fine with
error_setg(&error_fatal, ...), Markus?
No, I'm not.
I think this is a checkpatch job, supported by a suitable update to the docs in error.h.
Re: [Qemu-devel] [PATCH v6 1/5] util: Introduce error reporting functions with fatal/abort
In reply to Markus ArmbrusterMarkus Armbruster writes:
[...]
Quoted 1 line
As to the " " messages: surely you're joking, Mr. Feynman :)
BTW, completely off-topic, but I just wanted to say that's a great book :)
Cheers,
Lluis
PATCH v6 2/5 util: Use new error_report_fatal/abort instead of error_setg(&error_fatal/abort)
In reply to Lluís VilanovaReplaces all direct uses of 'error_setg(&error_fatal/abort)' with 'error_report_fatal/abort'. Also reimplements the former on top of the latter.
--- hw/block/fdc.c | 6 +++--- hw/ppc/spapr.c | 8 ++++---- hw/ppc/spapr_drc.c | 2 +- util/error.c | 9 +++------ 4 files changed, 11 insertions(+), 14 deletions(-)
hw/block/fdc.c +3 -3
@@ -347,9 +347,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]);
hw/ppc/spapr.c +4 -4
@@ -1039,7 +1039,7 @@ static void spapr_alloc_htab(sPAPRMachineState *spapr)* For HV KVM, host kernel will return -ENOMEM when requested * HTAB size can't be allocated. */ -error_setg (&error_abort,"Failed to allocate HTAB of requested size, try with smaller maxmem" ); +error_report_abort ("Failed to allocate HTAB of requested size, try with smaller maxmem" ); }else if (shift >0 ) {/* * Kernel handles htab, we don't need to allocate one
@@ -1048,7 +1048,7 @@ static void spapr_alloc_htab(sPAPRMachineState *spapr)* but we don't allow booting of such guests. */ if (shift != spapr->htab_shift) { -error_setg (&error_abort,"Failed to allocate HTAB of requested size, try with smaller maxmem" ); +error_report_abort ("Failed to allocate HTAB of requested size, try with smaller maxmem" ); } spapr->htab_shift = shift;
@@ -1079,10 +1079,10 @@ static void spapr_reset_htab(sPAPRMachineState *spapr) shift =kvmppc_reset_htab (spapr->htab_shift);if (shift <0 ) { -error_setg (&error_abort,"Failed to reset HTAB" ); +error_report_abort ("Failed to reset HTAB" ); }else if (shift >0 ) {if (shift != spapr->htab_shift) { -error_setg (&error_abort,"Requested HTAB allocation failed during reset" ); +error_report_abort ("Requested HTAB allocation failed during reset" ); }/* Tell readers to update their file descriptor */
hw/ppc/spapr_drc.c +1 -1
@@ -323,7 +323,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void *opaque,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 );
util/error.c +3 -6
@@ -30,15 +30,12 @@ Error *error_fatal;static void error_handle_fatal (Error **errp,Error *err) { +/* None of them has a hint, so error_report_err() is not necessary here */ if (errp == &error_abort) { -fprintf (stderr,"Unexpected error in %s() at %s:%d:\n" , - err->func, err->src, err->line); -error_report_err (err); -abort (); +error_report_abort_internal ("%s" , err->msg); }if (errp == &error_fatal) { -error_report_err (err); -exit (1 ); +error_report_fatal ("%s" , err->msg); } }
Re: [Qemu-devel] [PATCH v6 2/5] util: Use new error_report_fatal/abort instead of error_setg(&error_fatal/abort)
Quoted 18 lines · Lluís Vilanova
Replaces all direct uses of '
error_setg(&error_fatal/abort)' with 'error_report_fatal/abort'. Also reimplements the former on top of the latter.Signed-off-by Lluís Vilanova <[email protected]>--- hw/block/fdc.c | 6 +++--- hw/ppc/spapr.c | 8 ++++---- hw/ppc/spapr_drc.c | 2 +- util/error.c | 9 +++------ 4 files changed, 11 insertions(+), 14 deletions(-)hw/block/fdc.c +0
-0@@ -347,9 +347,9 @@ static int pick_geometry(FDrive *drv)
hw/block/fdc.c static int pick_geometry(FDrive *drv) · line 354
Quoted 10 lines
hw/block/fdc.c +3
-3/* 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]); }
Quoted 74 lines
hw/block/fdc.c +0
-0parse = &(fd_formats[match]);hw/ppc/spapr.c +4
-4@@ -1039,7 +1039,7 @@ static void spapr_alloc_htab(sPAPRMachineState *spapr)* For HV KVM, host kernel will return -ENOMEM when requested * HTAB size can't be allocated. */ -error_setg (&error_abort,"Failed to allocate HTAB of requested size, try with smaller maxmem" ); +error_report_abort ("Failed to allocate HTAB of requested size, try with smaller maxmem" ); }else if (shift >0 ) {/* * Kernel handles htab, we don't need to allocate one @@ -1048,7 +1048,7 @@ static void spapr_alloc_htab(sPAPRMachineState *spapr)* but we don't allow booting of such guests. */ if (shift != spapr->htab_shift) { -error_setg (&error_abort,"Failed to allocate HTAB of requested size, try with smaller maxmem" ); +error_report_abort ("Failed to allocate HTAB of requested size, try with smaller maxmem" ); } spapr->htab_shift = shift;@@ -1079,10 +1079,10 @@ static void spapr_reset_htab(sPAPRMachineState *spapr) shift =kvmppc_reset_htab (spapr->htab_shift);if (shift <0 ) { -error_setg (&error_abort,"Failed to reset HTAB" ); +error_report_abort ("Failed to reset HTAB" ); }else if (shift >0 ) {if (shift != spapr->htab_shift) { -error_setg (&error_abort,"Requested HTAB allocation failed during reset" ); +error_report_abort ("Requested HTAB allocation failed during reset" ); }/* Tell readers to update their file descriptor */ hw/ppc/spapr_drc.c +1
-1@@ -323,7 +323,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void *opaque,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 );util/error.c +3
-6@@ -30,15 +30,12 @@ Error *error_fatal;static void error_handle_fatal (Error **errp,Error *err) { +/* None of them has a hint, so error_report_err() is not necessary here */ if (errp == &error_abort) { -fprintf (stderr,"Unexpected error in %s() at %s:%d:\n" , - err->func, err->src, err->line); -error_report_err (err); -abort (); +error_report_abort_internal ("%s" , err->msg); }if (errp == &error_fatal) { -error_report_err (err); -exit (1 ); +error_report_fatal ("%s" , err->msg); } }
PATCH v6 3/5 util: [ppc] Use new error_report_fatal() instead of exit()
In reply to Lluís Vilanova--- target-ppc/kvm.c | 5 +-- target-ppc/translate.c | 7 ++-- target-ppc/translate_init.c | 80 +++++++++++++++++++++---------------------- 3 files changed, 44 insertions(+), 48 deletions(-)
target-ppc/kvm.c +2 -3
@@ -316,9 +316,8 @@ static long gethugepagesize(const char *mem_path) }while (ret !=0 && errno ==EINTR );if (ret !=0 ) { -fprintf (stderr,"Couldn't statfs() memory path: %s\n" , -strerror (errno)); -exit (1 ); +error_report_fatal ("Couldn't statfs() memory path: %s" , +strerror (errno)); }#define HUGETLBFS_MAGIC 0x958458f6
target-ppc/translate.c +3 -4
@@ -11588,10 +11588,9 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)break ; }if (tcg_check_temp_count ()) { -fprintf (stderr,"Opcode %02x %02x %02x (%08x) leaked temporaries\n" , -opc1 (ctx.opcode),opc2 (ctx.opcode),opc3 (ctx.opcode), - ctx.opcode); -exit (1 ); +error_report_fatal ("Opcode %02x %02x %02x (%08x) leaked temporaries" , +opc1 (ctx.opcode),opc2 (ctx.opcode),opc3 (ctx.opcode), + ctx.opcode); } }if (tb->cflags &CF_LAST_IO )
target-ppc/translate_init.c +39 -41
141 lines not on this page · raw message
PATCH v6 4/5 util: [ppc] Use new error_report_abort() instead of abort()
In reply to Lluís Vilanova--- target-ppc/kvm.c | 4 ++-- target-ppc/kvm_ppc.h | 15 +++++++++------ target-ppc/mmu-hash32.c | 5 +++-- target-ppc/mmu_helper.c | 3 +-- 4 files changed, 15 insertions(+), 12 deletions(-)
target-ppc/kvm.c +2 -2
@@ -587,7 +587,7 @@ static void kvm_get_one_spr(CPUState *cs, uint64_t id, int spr)default :/* Don't handle this size yet */ -abort (); +error_report_abort ("Unhandled size: %d" , id &KVM_REG_SIZE_MASK ); } } }
@@ -617,7 +617,7 @@ static void kvm_put_one_spr(CPUState *cs, uint64_t id, int spr)default :/* Don't handle this size yet */ -abort (); +error_report_abort ("Unhandled size: %d" , id &KVM_REG_SIZE_MASK ); } ret =kvm_vcpu_ioctl (cs,KVM_SET_ONE_REG , ®);
target-ppc/kvm_ppc.h +9 -6
@@ -9,6 +9,9 @@#ifndef __KVM_PPC_H__#define __KVM_PPC_H__ +#include "qemu/error-report.h" + +#define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU#ifdef CONFIG_KVM
@@ -215,36 +218,36 @@ static inline int kvmppc_get_htab_fd(bool write)static inline int kvmppc_save_htab (QEMUFile *f,int fd,size_t bufsize,int64_t max_ns) { -abort (); +error_report_abort (" " ); }static inline int kvmppc_load_htab_chunk (QEMUFile *f,int fd,uint32_t index,uint16_t n_valid,uint16_t n_invalid) { -abort (); +error_report_abort (" " ); }static inline uint64_t kvmppc_hash64_read_pteg (PowerPCCPU *cpu,target_ulong pte_index) { -abort (); +error_report_abort (" " ); }static inline void kvmppc_hash64_free_pteg (uint64_t token) { -abort (); +error_report_abort (" " ); }static inline void kvmppc_hash64_write_pte (CPUPPCState *env,target_ulong pte_index,target_ulong pte0,target_ulong pte1) { -abort (); +error_report_abort (" " ); }static inline bool kvmppc_has_cap_fixup_hcalls (void ) { -abort (); +error_report_abort (" " ); }static inline int kvmppc_enable_hwrng (void )
target-ppc/mmu-hash32.c +3 -2
@@ -21,6 +21,7 @@#include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "qemu/error-report.h" #include "sysemu/kvm.h" #include "kvm_ppc.h" #include "mmu-hash32.h"
@@ -56,7 +57,7 @@ static int ppc_hash32_pp_prot(int key, int pp, int nx)break ;default : -abort (); +error_report_abort ("Unhandled pp: %d" , pp); } }else {switch (pp) {
@@ -74,7 +75,7 @@ static int ppc_hash32_pp_prot(int key, int pp, int nx)break ;default : -abort (); +error_report_abort ("Unhandled pp: %d" , pp); } }if (nx ==0 ) {
target-ppc/mmu_helper.c +1 -2
@@ -1324,8 +1324,7 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,default :/* Caller's checks mean we should never get here for other models */ -abort (); -return -1 ; +error_report_abort ("Unhandled MMU model: %d" , env->mmu_model); }return ret;
Re: [PATCH v6 4/5] util: [ppc] Use new error_report_abort() instead of abort()
Quoted 10 lines · Lluís Vilanova
Signed-off-by Lluís Vilanova <[email protected]>--- target-ppc/kvm.c | 4 ++-- target-ppc/kvm_ppc.h | 15 +++++++++------ target-ppc/mmu-hash32.c | 5 +++-- target-ppc/mmu_helper.c | 3 +-- 4 files changed, 15 insertions(+), 12 deletions(-)
target-ppc/kvm_ppc.h static inline int kvmppc_get_htab_fd(bool write) · line 222
Quoted 6 lines
target-ppc/kvm_ppc.h +1
-1@@ -215,36 +218,36 @@ static inline int kvmppc_get_htab_fd(bool write)static inline int kvmppc_save_htab (QEMUFile *f,int fd,size_t bufsize,int64_t max_ns) { -abort (); +error_report_abort (" " ); }
I still strongly dislike this. Reporting an error message with nothing but a trailing whitespace is NOT helpful. Straight 'abort()' is better than this; if we can't come up with a useful message, then it is not worth using the message-handling interface.
Signature · 2 lines
Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Re: [PATCH v6 4/5] util: [ppc] Use new error_report_abort() instead of abort()
In reply to Lluís VilanovaQuoted 45 lines · Lluís Vilanova
Signed-off-by Lluís Vilanova <[email protected]>--- target-ppc/kvm.c | 4 ++-- target-ppc/kvm_ppc.h | 15 +++++++++------ target-ppc/mmu-hash32.c | 5 +++-- target-ppc/mmu_helper.c | 3 +-- 4 files changed, 15 insertions(+), 12 deletions(-)target-ppc/kvm.c +2
-2@@ -587,7 +587,7 @@ static void kvm_get_one_spr(CPUState *cs, uint64_t id, int spr)default :/* Don't handle this size yet */ -abort (); +error_report_abort ("Unhandled size: %d" , id &KVM_REG_SIZE_MASK ); } } }@@ -617,7 +617,7 @@ static void kvm_put_one_spr(CPUState *cs, uint64_t id, int spr)default :/* Don't handle this size yet */ -abort (); +error_report_abort ("Unhandled size: %d" , id &KVM_REG_SIZE_MASK ); } ret =kvm_vcpu_ioctl (cs,KVM_SET_ONE_REG , ®);target-ppc/kvm_ppc.h +3
-0@@ -9,6 +9,9 @@#ifndef __KVM_PPC_H__#define __KVM_PPC_H__ +#include "qemu/error-report.h" + +#define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU#ifdef CONFIG_KVM
target-ppc/kvm_ppc.h static inline int kvmppc_get_htab_fd(bool write) · line 221
Quoted 5 lines
target-ppc/kvm_ppc.h +1
-1@@ -215,36 +218,36 @@ static inline int kvmppc_get_htab_fd(bool write)static inline int kvmppc_save_htab (QEMUFile *f,int fd,size_t bufsize,int64_t max_ns) { -abort (); +error_report_abort (" " );
Nack. The empty message report is just awful. I don't think we should feel the need to get rid of every bare abort() or assert().
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH v6 5/5 doc: Introduce coding style for errors
In reply to Lluís VilanovaGives some general guidelines for reporting errors in QEMU.
--- HACKING | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
HACKING +37 -0
@@ -157,3 +157,40 @@ painful. These are: * you may assume that integers are 2s complement representation * you may assume that right shift of a signed integer duplicates the sign bit (ie it is an arithmetic shift, not a logical shift) + +7. Error reporting + +QEMU provides various mechanisms for reporting errors using a uniform format, +ensuring the user will receive them (e.g., shown in QMP when necessary). You +should use one of these mechanisms instead of manually reporting them (i.e., do +not use 'printf()', 'exit()' or 'abort()'). + +As a general rule, use the 'fatal' forms below for errors that can be triggered +by the user (e.g., commandline, hotplug, etc.), and the 'abort' forms for +programming errors that the user should not be able to trigger. + +7.1. Simple error messages + +The 'error_report*()' functions in "include/qemu/error-report.h" will +immediately report error messages to the user. + +WARNING: Do *not* use 'error_report_fatal()' or 'error_report_abort()' for +errors that are (or can be) triggered by guest code (e.g., some unimplemented +corner case in guest code translation or device code). Otherwise, that can be +abused by guest code to terminate QEMU. Instead, you should use +'error_report()'. + +7.2. Errors in user inputs + +The 'loc_*()' functions in "include/qemu/error-report.h" will extend the +messages from 'error_report*()' with references to locations in inputs provided +by the user (e.g., command line arguments or configuration files). + +7.3. More complex error management + +The functions in "include/qapi/error.h" can be used to accumulate error messages +in an 'Error' object, which can be propagated up the call chain where it is +finally reported. + +WARNING: The special 'error_fatal' and 'error_abort' objects follow the same +constraints as the 'error_report_fatal()' and 'error_report_abort()' functions.
Re: [Qemu-devel] [PATCH v6 5/5] doc: Introduce coding style for errors
Quoted 12 lines · Lluís Vilanova
Gives some general guidelines for reporting errors in QEMU.
Signed-off-by Lluís Vilanova <[email protected]>--- HACKING | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)HACKING +0
-0
HACKING painful. These are: · line 166
Quoted 10 lines
HACKING +7
-0@@ -157,3 +157,40 @@ painful. These are: * you may assume that integers are 2s complement representation * you may assume that right shift of a signed integer duplicates the sign bit (ie it is an arithmetic shift, not a logical shift) + +7. Error reporting + +QEMU provides various mechanisms for reporting errors using a uniform format, +ensuring the user will receive them (e.g., shown in QMP when necessary). You +should use one of these mechanisms instead of manually reporting them (i.e., do +not use 'printf()', 'exit()' or 'abort()').
The "do not use exit() or abort()" part applies only if we adopt your new error reporting functions.
HACKING painful. These are: · line 168
Quoted 2 lines
HACKING +2
-0+ +As a general rule, use the 'fatal' forms below for errors that can be triggered
Where's "below"?
HACKING painful. These are: · line 170
Quoted 2 lines
HACKING +2
-0+by the user (e.g., commandline, hotplug, etc.), and the 'abort' forms for +programming errors that the user should not be able to trigger.
This paragraph applies only if we adopt your new error reporting functions.
HACKING painful. These are: · line 175
Quoted 5 lines
HACKING +5
-0+ +7.1. Simple error messages + +The 'error_report*()' functions in "include/qemu/error-report.h" will +immediately report error messages to the user.
Suggest "the human user".
HACKING painful. These are: · line 181
Quoted 6 lines
HACKING +6
-0+ +WARNING: Do *not* use 'error_report_fatal()' or 'error_report_abort()' for +errors that are (or can be) triggered by guest code (e.g., some unimplemented +corner case in guest code translation or device code). Otherwise, that can be +abused by guest code to terminate QEMU. Instead, you should use +'error_report()'.
This paragraph applies only if we adopt your new error reporting functions. Without them: "Do *not* exit() or abort() on errors that can be triggered...", and scratch the last sentence.
HACKING painful. These are: · line 187
Quoted 6 lines
HACKING +6
-0+ +7.2. Errors in user inputs + +The 'loc_*()' functions in "include/qemu/error-report.h" will extend the +messages from 'error_report*()' with references to locations in inputs provided +by the user (e.g., command line arguments or configuration files).
This is probably too terse to help much on its own. Perhaps error-report.h should have usage information, like error.h.
HACKING painful. These are: · line 191
Quoted 4 lines
HACKING +4
-0+ +7.3. More complex error management + +The functions in "include/qapi/error.h" can be used to accumulate error messages
Long line.
HACKING painful. These are: · line 193
Quoted 2 lines
HACKING +2
-0+in an 'Error' object, which can be propagated up the call chain where it is +finally reported.
"Accumulate" suggests accumulating multiple error messages, and that's not quite right. Perhaps: "to capture an error message".
"where it is finally reported" is inaccurate. It may or may not be reported. Perhaps: "until it is handled, and possibly reported to the user".
HACKING painful. These are: · line 196
Quoted 3 lines
HACKING +3
-0+ +WARNING: The special 'error_fatal' and 'error_abort' objects follow the same +constraints as the 'error_report_fatal()' and 'error_report_abort()' functions.
Without your new error reporting functions: "Do *not* use &error_fatal and &error_abort to handle errors that can be triggered by guest code, just like exit() and abort()."
Suggest to explicitly point to the big usage comment in error.h.
Re: [Qemu-devel] [PATCH v6 5/5] doc: Introduce coding style for errors
Quoted 27 lines · Markus Armbruster
Quoted 12 lines · Lluís Vilanova
Gives some general guidelines for reporting errors in QEMU.
Signed-off-by Lluís Vilanova <[email protected]>---
HACKING | 37 +++++++++++++++++++++++++++++++++++++1 file changed, 37 insertions(+)HACKING +0
-0HACKING painful. These are: · line 166
Quoted 10 lines
HACKING +7
-0@@ -157,3 +157,40 @@ painful. These are: * you may assume that integers are 2s complement representation * you may assume that right shift of a signed integer duplicates the sign bit (ie it is an arithmetic shift, not a logical shift) + +7. Error reporting + +QEMU provides various mechanisms for reporting errors using a uniform format, +ensuring the user will receive them (e.g., shown in QMP when necessary). You +should use one of these mechanisms instead of manually reporting them (i.e., do +not use 'printf()', 'exit()' or 'abort()').The "do not use
exit()orabort()" part applies only if we adopt your new error reporting functions.
Quoted 4 lines
HACKING painful. These are: · line 168
Quoted 2 lines
HACKING +2
-0+ +As a general rule, use the 'fatal' forms below for errors that can be triggeredWhere's "below"?
It's the following two sections, sorry.
Quoted 25 lines
HACKING painful. These are: · line 170
Quoted 2 lines
HACKING +2
-0+by the user (e.g., commandline, hotplug, etc.), and the 'abort' forms for +programming errors that the user should not be able to trigger.This paragraph applies only if we adopt your new error reporting functions.
HACKING painful. These are: · line 175
Quoted 5 lines
HACKING +5
-0+ +7.1. Simple error messages + +The 'error_report*()' functions in "include/qemu/error-report.h" will +immediately report error messages to the user.Suggest "the human user".
HACKING painful. These are: · line 181
Quoted 6 lines
HACKING +6
-0+ +WARNING: Do *not* use 'error_report_fatal()' or 'error_report_abort()' for +errors that are (or can be) triggered by guest code (e.g., some unimplemented +corner case in guest code translation or device code). Otherwise, that can be +abused by guest code to terminate QEMU. Instead, you should use +'error_report()'.This paragraph applies only if we adopt your new error reporting functions. Without them: "Do *not*
exit()orabort()on errors that can be triggered...", and scratch the last sentence.
Quoted 9 lines
HACKING painful. These are: · line 187
Quoted 6 lines
HACKING +6
-0+ +7.2. Errors in user inputs + +The 'loc_*()' functions in "include/qemu/error-report.h" will extend the +messages from 'error_report*()' with references to locations in inputs provided +by the user (e.g., command line arguments or configuration files).This is probably too terse to help much on its own. Perhaps
error-report.hshould have usage information, likeerror.h.
I can try adding that, although I've barely used this part of the interface.
Quoted 25 lines
HACKING painful. These are: · line 191
Quoted 4 lines
HACKING +4
-0+ +7.3. More complex error management + +The functions in "include/qapi/error.h" can be used to accumulate error messagesLong line.
HACKING painful. These are: · line 193
Quoted 2 lines
HACKING +2
-0+in an 'Error' object, which can be propagated up the call chain where it is +finally reported."Accumulate" suggests accumulating multiple error messages, and that's not quite right. Perhaps: "to capture an error message".
"where it is finally reported" is inaccurate. It may or may not be reported. Perhaps: "until it is handled, and possibly reported to the user".
HACKING painful. These are: · line 196
Quoted 3 lines
HACKING +3
-0+ +WARNING: The special 'error_fatal' and 'error_abort' objects follow the same +constraints as the 'error_report_fatal()' and 'error_report_abort()' functions.Without your new error reporting functions: "Do *not* use
&error_fataland&error_abortto handle errors that can be triggered by guest code, just likeexit()andabort()."
Quoted 1 line
Suggest to explicitly point to the big usage comment in
error.h.
Thanks,
Lluis
Re: [Qemu-devel] [PATCH v6 5/5] doc: Introduce coding style for errors
Quoted 14 lines · Lluís Vilanova
Quoted 12 lines · Markus Armbruster
Quoted 11 lines · Lluís Vilanova
Gives some general guidelines for reporting errors in QEMU.
Signed-off-by Lluís Vilanova <[email protected]>---
HACKING | 37 +++++++++++++++++++++++++++++++++++++1 file changed, 37 insertions(+)HACKING +0
-0
[...]
Quoted 10 lines
Quoted 8 lines
HACKING painful. These are: · line 187
Quoted 5 lines
+7.2. Errors in user inputs
HACKING +4
-0+ +The 'loc_*()' functions in "include/qemu/error-report.h" will extend the +messages from 'error_report*()' with references to locations in inputs provided +by the user (e.g., command line arguments or configuration files).This is probably too terse to help much on its own. Perhaps
error-report.hshould have usage information, likeerror.h.I can try adding that, although I've barely used this part of the interface.
Documenting something you're not familiar with risks messy and laborious review. I'd simply drop this section for now. If you have appetite for more after you got the rest in, you can do another patch.
[...]
Re: [Qemu-devel] [PATCH v6 5/5] doc: Introduce coding style for errors
Quoted 22 lines · Markus Armbruster
Quoted 14 lines · Lluís Vilanova
Quoted 12 lines · Markus Armbruster
Quoted 11 lines · Lluís Vilanova
Gives some general guidelines for reporting errors in QEMU.
Signed-off-by Lluís Vilanova <[email protected]>---
HACKING | 37 +++++++++++++++++++++++++++++++++++++1 file changed, 37 insertions(+)HACKING +0
-0[...]
Quoted 6 lines
Quoted 5 lines
Quoted 5 lines
+7.2. Errors in user inputs
HACKING +4
-0+ +The 'loc_*()' functions in "include/qemu/error-report.h" will extend the +messages from 'error_report*()' with references to locations in inputs provided +by the user (e.g., command line arguments or configuration files).
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
This is probably too terse to help much on its own. Perhaps
error-report.hshould have usage information, likeerror.h.I can try adding that, although I've barely used this part of the interface.
Documenting something you're not familiar with risks messy and laborious review. I'd simply drop this section for now. If you have appetite for more after you got the rest in, you can do another patch.
Mmmm, I still think that a terse reference is better at directing developers to the right header than just not commenting it. I think that this type of patches are not funny to anyone, so this risks having no metion of loc_* in the near/mid future.
But hey, I might just be too pessimistic :)
Thanks,
Lluis
Re: [Qemu-devel] [PATCH v6 5/5] doc: Introduce coding style for errors
Quoted 33 lines · Lluís Vilanova
Quoted 22 lines · Markus Armbruster
Quoted 14 lines · Lluís Vilanova
Quoted 12 lines · Markus Armbruster
Quoted 11 lines · Lluís Vilanova
Gives some general guidelines for reporting errors in QEMU.
Signed-off-by Lluís Vilanova <[email protected]>---
HACKING | 37 +++++++++++++++++++++++++++++++++++++1 file changed, 37 insertions(+)HACKING +0
-0[...]
Quoted 6 lines
Quoted 5 lines
Quoted 5 lines
+7.2. Errors in user inputs
HACKING +4
-0+ +The 'loc_*()' functions in "include/qemu/error-report.h" will extend the +messages from 'error_report*()' with references to locations in inputs provided +by the user (e.g., command line arguments or configuration files).Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
This is probably too terse to help much on its own. Perhaps
error-report.hshould have usage information, likeerror.h.I can try adding that, although I've barely used this part of the interface.
Documenting something you're not familiar with risks messy and laborious review. I'd simply drop this section for now. If you have appetite for more after you got the rest in, you can do another patch.
Quoted 6 lines
Mmmm, I still think that a terse reference is better at directing developers to the right header than just not commenting it. I think that this type of patches are not funny to anyone, so this risks having no metion of loc_* in the near/mid future.
But hey, I might just be too pessimistic :)
If you want to cover error locations in HACKING briefly, that's okay with me, but it needs to be correct. I'll look over your proposed patch again.
Re: [Qemu-devel] [PATCH v6 5/5] doc: Introduce coding style for errors
In reply to Lluís VilanovaQuoted 3 lines · Lluís Vilanova
Gives some general guidelines for reporting errors in QEMU.
Signed-off-by Lluís Vilanova <[email protected]>
I started re-reviewing this, but my suggestions quickly became a rewrite (sorry), so I'm just posting just that. I'll turn it into a proper patch you can include in your series.
7. Error handling and reporting
7.1 Reporting errors to the human user
Do not use printf(), fprintf() or monitor_printf(). Instead, use error_report() or error_vreport() from error-report.h. This ensures the error is reported in the right place (current monitor or stderr), and in a uniform format.
Use error_printf() & friends to print additional information.
error_report() prints the current location. In certain common cases like command line parsing, the current location is tracked automatically. To manipulate it manually, use the loc_*() from error-report.h.
7.2 Propagating errors
An error can't always be reported to the user right where it's detected, but often needs to be propagated up the call chain to a place that can handle it. This can be done in various ways.
The most flexible one is Error objects. See error.h for usage information.
Use the simplest suitable method to communicate success / failure to callers. Stick to common methods: non-negative on success / -1 on error, non-negative / -errno, non-null / null, or Error objects.
Example: when a function returns a non-null pointer on success, and it can fail only in one way (as far as the caller is concerned), returning null on failure is just fine, and certainly simpler and a lot easier on the eyes than propagating an Error object through an Error ** parameter.
Example: when a function's callers need to report details on failure only the function really knows, use Error **, and set suitable errors.
Do not report an error to the user when you're also returning an error for somebody else to handle. Leave the reporting to the place that consumes the error returned.
7.3 Handling errors
Calling exit() is fine when handling configuration errors during startup. It's problematic during normal operation. In particular, monitor commands should never exit().
Do not call exit() or abort() to handle an error that can be triggered by the guest (e.g., some unimplemented corner case in guest code translation or device emulation). Guests should not be able to terminate QEMU.
Note that &error_fatal is just another way to exit(1), and &error_abort is just another way to abort().