On 9/24/19 3:08 PM, Vladimir Sementsov-Ogievskiy wrote: > Here is introduced ERRP_FUNCTION_BEGIN macro, to be used at start of > functions with errp parameter. > > It has three goals: > > 1. Fix issue with error_fatal & error_append_hint: user can't see these > hints, because exit() happens in error_setg earlier than hint is > appended. [Reported by Greg Kurz] > > 2. Fix issue with error_abort & error_propagate: when we wrap > error_abort by local_err+error_propagate, resulting coredump will > refer to error_propagate and not to the place where error happened. > (the macro itself doesn't fix the issue, but it allows to [3.] drop all > local_err+error_propagate pattern, which will definitely fix the issue) > [Reported by Kevin Wolf] > > 3. Drop local_err+error_propagate pattern, which is used to workaround > void functions with errp parameter, when caller wants to know resulting > status. (Note: actually these functions could be merely updated to > return int error code). > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> > --- >
> +/* > + * ERRP_FUNCTION_BEGIN > + * > + * This macro is created to be the first line of a function with Error **errp > + * parameter. Since you're going with the reduced scope of only touching functions with error_append_hint, we may want to tweak this sentence to call out only the functions that REQUIRE the use of this macro (if they contain *errp or error_apend_hint), while mentioning that it is still safe to use on any function with an errp parameter. I'm hoping Markus will be able to chime in with his preferences soon. > + * > + * If errp is NULL or points to error_fatal, it is rewritten to point to a > + * local Error object, which will be automatically propagated to the original > + * errp on function exit (see error_propagator_cleanup). > + * > + * After invocation of this macro it is always safe to dereference errp > + * (as it's not NULL anymore) and to append hints (by error_append_hint) > + * (as, if it was error_fatal, we swapped it with a local_error to be > + * propagated on cleanup). > + * > + * Note: we don't wrap the error_abort case, as we want resulting coredump > + * to point to the place where the error happened, not to error_propagate. > + */ > +#define ERRP_FUNCTION_BEGIN() \ > +g_auto(ErrorPropagator) __auto_errp_prop = {.errp = errp}; \ > +errp = ((errp == NULL || *errp == error_fatal) ? \ > + &__auto_errp_prop.local_err : errp) > + Reviewed-by: Eric Blake <ebl...@redhat.com> -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org