At 07/02/2011 05:43 AM, Eric Blake Write: > Systemtap 1.2 <sys/sdt.h> tried to expand STAP_PROBE3 into an > initialization: > volatile __typeof__(arg) foo = arg; > but that fails if arg was declared as 'char arg[100]'. > Rather than make all callers to PROBE deal with the stupidity > of <sys/sdt.h>, we instead make PROBE cast away the problem. > Some of this preprocessor abuse copies ideas in src/libvirt.c. > > * daemon/libvirtd.h (PROBE): Add casts to all arguments, using... > (VIR_ADD_CASTS, VIR_ADD_CAST, VIR_ADD_CAST2, VIR_ADD_CAST3) > (VIR_ADD_CAST_EXPAND, VIR_ADD_CAST_PASTE, VIR_COUNT_ARGS) > (VIR_ARG5, PROBE_EXPAND): New macros. > Reported by Wen Congyang. > --- > > This took me entirely too long to come up with. It works for me > with systemtap 1.4; if I can get feedback from systemtap 1.2 and > 1.3 users, then I'll gladly apply it, and we can forget about > having to do stupid casts or other workarounds at every PROBE > client. It works for me with systemtap 1.2.9. > > daemon/libvirtd.h | 32 +++++++++++++++++++++++++++++++- > 1 files changed, 31 insertions(+), 1 deletions(-) > > diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h > index 6c604fc..2f0987e 100644 > --- a/daemon/libvirtd.h > +++ b/daemon/libvirtd.h > @@ -46,11 +46,41 @@ > # define LIBVIRTD_PROBES_H > # include "probes.h" > # endif /* LIBVIRTD_PROBES_H */ > + > +/* Systemtap 1.2 headers have a bug where they cannot handle a > + * variable declared with array type. Work around this by casting all > + * arguments. This is some gross use of the preprocessor because > + * PROBE is a var-arg macro, but it is better than the alternative of > + * making all callers to PROBE have to be aware of the issues. And > + * hopefully, if we ever add a call to PROBE with other than 2 or 3 > + * end arguments, you can figure out the pattern to extend this hack. > + */ > +# define VIR_COUNT_ARGS(...) VIR_ARG5(__VA_ARGS__, 4, 3, 2, 1) > +# define VIR_ARG5(_1, _2, _3, _4, _5, ...) _5 > +# define VIR_ADD_CAST_EXPAND(a, b, ...) VIR_ADD_CAST_PASTE(a, b, __VA_ARGS__) > +# define VIR_ADD_CAST_PASTE(a, b, ...) a##b(__VA_ARGS__) > + > +/* The double cast is necessary to silence gcc warnings; any pointer > + * can safely go to intptr_t and back to void *, which collapses > + * arrays into pointers; while any integer can be widened to intptr_t > + * then cast to void *. */ > +# define VIR_ADD_CAST(a) ((void *)(intptr_t)(a)) > +# define VIR_ADD_CAST2(a, b) \ > + VIR_ADD_CAST(a), VIR_ADD_CAST(b) > +# define VIR_ADD_CAST3(a, b, c) \ > + VIR_ADD_CAST(a), VIR_ADD_CAST(b), VIR_ADD_CAST(c) > + > +# define VIR_ADD_CASTS(...) \ > + VIR_ADD_CAST_EXPAND(VIR_ADD_CAST, VIR_COUNT_ARGS(__VA_ARGS__), \ > + __VA_ARGS__) > + > +# define PROBE_EXPAND(NAME, ARGS) NAME(ARGS) > # define PROBE(NAME, FMT, ...) \ > VIR_DEBUG_INT("trace." __FILE__ , __func__, __LINE__, \ > #NAME ": " FMT, __VA_ARGS__); \ > if (LIBVIRTD_ ## NAME ## _ENABLED()) { \ > - LIBVIRTD_ ## NAME(__VA_ARGS__); \ > + PROBE_EXPAND(LIBVIRTD_ ## NAME, \ > + VIR_ADD_CASTS(__VA_ARGS__)); \ > } > # else > # define PROBE(NAME, FMT, ...) \ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list