It's a common idiom: Error *local_err = NULL; .... foo(&local_err); ... if (local_err) { error_propagate(errp, local_err); return; }
Unfortunately it means that call to foo(&local_err) will not abort even if errp is set to error_abort. Instead, we get an abort at error_propagate which is too late. To fix, add an API to check errp and set local_err to error_abort if errp is error_abort. Signed-off-by: Michael S. Tsirkin <m...@redhat.com> --- include/qapi/error.h | 5 +++++ util/error.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/include/qapi/error.h b/include/qapi/error.h index f44c451..8246a62 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -88,6 +88,11 @@ const char *error_get_pretty(Error *err); void error_report_err(Error *); /** + * Init a local error. It must be propagated to errp using error_propagate. + */ +Error *error_init_local(Error **errp); + +/** * Propagate an error to an indirect pointer to an error. This function will * always transfer ownership of the error reference and handles the case where * dst_err is NULL correctly. Errors after the first are discarded. diff --git a/util/error.c b/util/error.c index ccf29ea..7489967 100644 --- a/util/error.c +++ b/util/error.c @@ -28,6 +28,11 @@ static bool error_is_abort(Error **errp) return errp && *errp && (*errp)->err_class == ERROR_CLASS_MAX; } +Error *error_init_local(Error **errp) +{ + return error_is_abort(errp) ? *errp : NULL; +} + void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) { Error *err; -- MST