[libvirt] [PATCH] Rewrite the way mockable functions are handled.

Daniel P. Berrange berrange at redhat.com
Thu Jul 13 13:22:41 UTC 2017


On Thu, Jul 13, 2017 at 02:33:57PM +0200, Martin Kletzander wrote:
> On Thu, Jul 13, 2017 at 12:25:50PM +0100, Daniel P. Berrange wrote:
> > On Thu, Jul 13, 2017 at 01:14:12PM +0200, Martin Kletzander wrote:
> > > On Wed, Jul 12, 2017 at 05:06:22PM +0100, Daniel P. Berrange wrote:
> > > > Currently any mockable functions are marked with attributes
> > > > noinline, noclone and weak. This prevents the compiler from
> > > > optimizing away the impl of these functions.
> > > >
> > > > It has an unfortunate side effect with the libtool convenience
> > > > libraries, if executables directly link to them. For example
> > > > virlockd, virlogd both link to libvirt_util.la  When this is
> > > > done, the linker does not consider weak symbols as being
> > > > undefined, so it never copies them into the final executable.
> > > >
> > > > In this new approach, we stop annotating the headers entirely.
> > > > Instead we create a weak function alias in the source.
> > > >
> > > >   int fooImpl(void) {
> > > >      ..the real code..
> > > >   }
> > > >
> > > >   int foo(void) __attribute__((noinline, noclone, weak, alias("fooImpl"))
> > > >
> > > > If any functions in the same file call "foo", this prevents the
> > > > optimizer from inlining any part of fooImpl. When linking to the
> > > > libtool convenience static library, we also get all the symbols
> > > > present. Finally the test suite can just directly define a
> > > > 'foo' function in its source, removing the need to use LD_PRELOAD
> > > > (though removal of LD_PRELOADS is left for a future patch).
> > > >
> > > 
> > > What are you using for tag navigation?  With this macro-defined
> > > functions I cannot easily jump to them (the main reason why I don't like
> > > macros defining functions).
> > 
> > Grep & historic knowledge :-)
> > 
> > >                              I would very much prefer if
> > > ATTRIBUTE_MOCKABLE just took a parameter like this:
> > > 
> > > #define ATTRIBUTE_MOCKABLE(func) __attribute__((noinline, noclone, weak, alias(#func "Impl"))
> > > 
> > > (written by hand, don't take mu word for it working out of the box) and
> > > the original function would be left untouched.
> > 
> > Yeah, that is certainly a valid alternative. I was not entirely happy
> > with the results I get here. As long as we don't mind repeating the
> > arg list in both places, your approach is more attractive, despite
> > the duplication.
> > 
> 
> I think we don't if we do:
> 
> #define VIR_MOCKABLE(ret, name) typeof(name ## Impl) name \
>    __attribute__((noinline, weak, __alias__(#name "Impl")));
> 
> or can't this be done for functions?  It worked when I tried it now.

I've never tried typeof in this way, so I guess we can experiment.

> I have one more idea, though.  So that we don't have to double-type the
> actual definition of the Impl function, we can make it static.  What if
> we make *all* functions static and only add weak aliases to those that
> are supposed to be used outside the file?  That is after we deal with
> the Darwin case, of course.

NB, I orignally marked the funtions as static, but clang complains that
they are unused, despite being referenced from an alias annotation.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the libvir-list mailing list