[libvirt] [PATCH] build: work around older systemtap header
Wen Congyang
wency at cn.fujitsu.com
Mon Jul 4 00:54:25 UTC 2011
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, ...) \
More information about the libvir-list
mailing list