[lttng-dev] Follow-up on LTTng-UST static linking problem

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Fri Feb 3 17:56:38 EST 2012


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



More information about the lttng-dev mailing list