[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