Here is introduced ERRP_AUTO_PROPAGATE macro, to be used at start of functions with errp OUT parameter.
It has three goals: 1. Fix issue with error_fatal & error_prepend/error_append_hint: user can't see this additional information, because exit() happens in error_setg earlier than information is added. [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). To achieve these goals, we need to add invocation of the macro at start of functions, which needs error_prepend/error_append_hint (1.); add invocation of the macro at start of functions which do local_err+error_propagate scenario the check errors, drop local errors from them and just use *errp instead (2., 3.). Signed-off-by: Vladimir Sementsov-Ogievskiy <vsement...@virtuozzo.com> Reviewed-by: Eric Blake <ebl...@redhat.com> --- CC: Gerd Hoffmann <kra...@redhat.com> CC: "Gonglei (Arei)" <arei.gong...@huawei.com> CC: Eduardo Habkost <ehabk...@redhat.com> CC: Igor Mammedov <imamm...@redhat.com> CC: Laurent Vivier <lviv...@redhat.com> CC: Amit Shah <a...@kernel.org> CC: Kevin Wolf <kw...@redhat.com> CC: Max Reitz <mre...@redhat.com> CC: John Snow <js...@redhat.com> CC: Ari Sundholm <a...@tuxera.com> CC: Pavel Dovgalyuk <pavel.dovga...@ispras.ru> CC: Paolo Bonzini <pbonz...@redhat.com> CC: Stefan Hajnoczi <stefa...@redhat.com> CC: Fam Zheng <f...@euphon.net> CC: Stefan Weil <s...@weilnetz.de> CC: Ronnie Sahlberg <ronniesahlb...@gmail.com> CC: Peter Lieven <p...@kamp.de> CC: Eric Blake <ebl...@redhat.com> CC: "Denis V. Lunev" <d...@openvz.org> CC: Markus Armbruster <arm...@redhat.com> CC: Alberto Garcia <be...@igalia.com> CC: Jason Dillaman <dilla...@redhat.com> CC: Wen Congyang <wencongya...@huawei.com> CC: Xie Changlong <xiechanglon...@gmail.com> CC: Liu Yuan <namei.u...@gmail.com> CC: "Richard W.M. Jones" <rjo...@redhat.com> CC: Jeff Cody <codypr...@gmail.com> CC: "Marc-André Lureau" <marcandre.lur...@redhat.com> CC: "Daniel P. Berrangé" <berra...@redhat.com> CC: Richard Henderson <r...@twiddle.net> CC: Greg Kurz <gr...@kaod.org> CC: "Michael S. Tsirkin" <m...@redhat.com> CC: Marcel Apfelbaum <marcel.apfelb...@gmail.com> CC: Beniamino Galvani <b.galv...@gmail.com> CC: Peter Maydell <peter.mayd...@linaro.org> CC: "Cédric Le Goater" <c...@kaod.org> CC: Andrew Jeffery <and...@aj.id.au> CC: Joel Stanley <j...@jms.id.au> CC: Andrew Baumann <andrew.baum...@microsoft.com> CC: "Philippe Mathieu-Daudé" <phi...@redhat.com> CC: Antony Pavlov <antonynpav...@gmail.com> CC: Jean-Christophe Dubois <j...@tribudubois.net> CC: Peter Chubb <peter.ch...@nicta.com.au> CC: Subbaraya Sundeep <sundeep.l...@gmail.com> CC: Eric Auger <eric.au...@redhat.com> CC: Alistair Francis <alist...@alistair23.me> CC: "Edgar E. Iglesias" <edgar.igles...@gmail.com> CC: Stefano Stabellini <sstabell...@kernel.org> CC: Anthony Perard <anthony.per...@citrix.com> CC: Paul Durrant <p...@xen.org> CC: Paul Burton <pbur...@wavecomp.com> CC: Aleksandar Rikalo <arik...@wavecomp.com> CC: Chris Wulff <crwu...@gmail.com> CC: Marek Vasut <ma...@denx.de> CC: David Gibson <da...@gibson.dropbear.id.au> CC: Cornelia Huck <coh...@redhat.com> CC: Halil Pasic <pa...@linux.ibm.com> CC: Christian Borntraeger <borntrae...@de.ibm.com> CC: "Hervé Poussineau" <hpous...@reactos.org> CC: Xiao Guangrong <xiaoguangrong.e...@gmail.com> CC: Aurelien Jarno <aurel...@aurel32.net> CC: Aleksandar Markovic <amarko...@wavecomp.com> CC: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk> CC: Jason Wang <jasow...@redhat.com> CC: Laszlo Ersek <ler...@redhat.com> CC: Yuval Shaia <yuval.sh...@oracle.com> CC: Palmer Dabbelt <pal...@sifive.com> CC: Sagar Karandikar <sag...@eecs.berkeley.edu> CC: Bastian Koppelmann <kbast...@mail.uni-paderborn.de> CC: David Hildenbrand <da...@redhat.com> CC: Thomas Huth <th...@redhat.com> CC: Eric Farman <far...@linux.ibm.com> CC: Matthew Rosato <mjros...@linux.ibm.com> CC: Hannes Reinecke <h...@suse.com> CC: Michael Walle <mich...@walle.cc> CC: Artyom Tarasenko <atar4q...@gmail.com> CC: Stefan Berger <stef...@linux.ibm.com> CC: Samuel Thibault <samuel.thiba...@ens-lyon.org> CC: Alex Williamson <alex.william...@redhat.com> CC: Tony Krowiak <akrow...@linux.ibm.com> CC: Pierre Morel <pmo...@linux.ibm.com> CC: Michael Roth <mdr...@linux.vnet.ibm.com> CC: Hailiang Zhang <zhang.zhanghaili...@huawei.com> CC: Juan Quintela <quint...@redhat.com> CC: "Dr. David Alan Gilbert" <dgilb...@redhat.com> CC: Luigi Rizzo <ri...@iet.unipi.it> CC: Giuseppe Lettieri <g.letti...@iet.unipi.it> CC: Vincenzo Maffione <v.maffi...@gmail.com> CC: Jan Kiszka <jan.kis...@siemens.com> CC: Anthony Green <gr...@moxielogic.com> CC: Stafford Horne <sho...@gmail.com> CC: Guan Xuetao <g...@mprc.pku.edu.cn> CC: Max Filippov <jcmvb...@gmail.com> CC: qemu-bl...@nongnu.org CC: integrat...@gluster.org CC: sheep...@lists.wpkg.org CC: qemu-...@nongnu.org CC: xen-devel@lists.xenproject.org CC: qemu-...@nongnu.org CC: qemu-s3...@nongnu.org CC: qemu-ri...@nongnu.org include/qapi/error.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/include/qapi/error.h b/include/qapi/error.h index d6898d833b..47238d9065 100644 --- a/include/qapi/error.h +++ b/include/qapi/error.h @@ -345,6 +345,44 @@ void error_set_internal(Error **errp, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(6, 7); +typedef struct ErrorPropagator { + Error *local_err; + Error **errp; +} ErrorPropagator; + +static inline void error_propagator_cleanup(ErrorPropagator *prop) +{ + error_propagate(prop->errp, prop->local_err); +} + +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ErrorPropagator, error_propagator_cleanup); + +/* + * ERRP_AUTO_PROPAGATE + * + * This macro is created to be the first line of a function with Error **errp + * OUT parameter. It's needed only in cases where we want to use error_prepend, + * error_append_hint or dereference *errp. It's still safe (but useless) in + * other cases. + * + * 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 add information (by error_prepend or + * 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_AUTO_PROPAGATE() \ + g_auto(ErrorPropagator) _auto_errp_prop = {.errp = errp}; \ + errp = ((errp == NULL || *errp == error_fatal) \ + ? &_auto_errp_prop.local_err : errp) + /* * Special error destination to abort on error. * See error_setg() and error_propagate() for details. -- 2.21.0 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel