[lttng-dev] Follow-up on LTTng-UST static linking problem (probably fixed)

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Sat Feb 4 14:40:46 EST 2012


Hi Sébastien,

Can you try with lttng-ust commit:

commit 628e1d81fe575cfd281d8e0758b672b23d890c09
Author: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
Date:   Sat Feb 4 14:37:34 2012 -0500

    Fix static provider linking: introduce TRACEPOINT_PROBE_DYNAMIC_LINKAGE
    
    We need to emit an unresolved symbol in the case where the provider is
    put into a statically linked library, otherwise the linker removes the
    provider object.
    
    See README for details.
    
    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>

You just have to update lttng-ust. If you used static linking to link
the probes, you don't need to add any defines (the new
TRACEPOINT_PROBE_DYNAMIC_LINKAGE is just for the case where the provider
is expected to be found into a LD_PRELOAD'd .so).

Thanks,

Mathieu

* Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote:
> Hi Sébastien,
> 
> I think I found a very good lead into what might be causing your
> problem.
> 
> When bundling the LTTng-UST probes into a static library (.a), in the
> following phases where we link this .a with the application, gcc
> discards all objects that have no outside reference from the application
> (see ld(1) --whole-archive option for explanation).
> 
> But we don't want those libraries to be removed, because they contain
> the probes. Their "side-effect" is their constructors/destructors, which
> registers them to lttng-ust, but the linker does not care about that.
> 
> So one solution might be to use
> 
> gcc -Wl,--undefined=symbol -lmyustprobe
> 
> (and maybe add a symbol to each ust probe, which we can target) to let
> the linker know that it needs to keep the UST probe .o.
> 
> I have some crude example code that helps reproducing this particular
> problem:
> 
> Makefile:
> 
> s: s.c sl.a
>         gcc -static -L.  -Wl,--undefined=myinit2 -o s s.c -lsl
> 
> sl.a: sl.c sl2.c sl3.c
>         gcc -c -o sl.o sl.c
>         gcc -c -o sl2.o sl2.c
>         gcc -c -o sl3.o sl3.c
>         ar rcs libsl.a sl.o sl2.o sl3.o
> 
> s.h:
> void testfct(void);
> 
> s.c:
> #include <stdio.h>
> #include "s.h"
> 
> int main()
> {
>         printf("main\n");
>         testfct();
>         return 0;
> }
> 
> sl.c:
> #include <stdio.h>
> #include "s.h"
> 
> void testfct(void)
> {
>         printf("testfct\n");
> }
> 
> static
> void __attribute__((constructor)) myinit(void)
> {
>         printf("constructor run\n");
> }
> 
> sl2.c:
> #include <stdio.h>
> #include "s.h"
> 
> void __attribute__((constructor)) myinit2(void)
> {
>         printf("constructor 2 run\n");
> }
> 
> sl3.c:
> #include <stdio.h>
> #include "s.h"
> 
> void __attribute__((constructor, externally_visible)) myinit(void)
> {
>         printf("constructor 3 run\n");
> }
> 
> result:
> constructor run
> constructor 2 run
> main
> testfct
> 
> As you see, sl.c constructor is executed, because main calls testfct.
> sl2.c constructor is also executed, because I added the --undefined. But
> sl3.c constructor is just not executed.
> 
> Playing with "nm" to list the symbols in each .o, .a and the final
> executable shows that the linker removes the sl3.o symbols from the
> final executable when linking the final executable.
> 
> Thoughts ?
> 
> Thanks,
> 
> Mathieu
> 
> -- 
> Mathieu Desnoyers
> Operating System Efficiency R&D Consultant
> EfficiOS Inc.
> http://www.efficios.com

-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list