Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared Library Constructor is not executed

I have the following problem. I write a shared library

#include <stdio.h>
#include <stdlib.h>

static void __attribute__ ((constructor)) test_init(void);
static void __attribute__ ((destructor))  test_clean(void);

/*  Initialization  */
static void     test_init(void){
        fprintf(stderr,"initialized\n");
        fflush(stderr);
}
/*  CleanUp */
static void test_clean(void){
        fprintf(stderr,"cleaned up\n");
        fflush(stderr);
}

double  test (double x){
    return  2.0*x;
}

And compile it using

gcc -c -fPIC testlib.c -o testlib.o

ld -shared -o libtest.so testlib.o

Then I include it into a test program

#include <stdio.h>
#include <stdlib.h>
extern double   test(double x);
void    main(void){

    printf("%.10e\n",test(10.0));
}

which I compile and start using

gcc testprog.c -o testprog -L. -ltest

LD_LIBRARY_PATH=. ./testprog

Then the output is given by

2.0000000000e+01

which means that the constructor/destructor are not executed. On the other hand, if I compile

ar rvs testlib.a testlib.o

gcc testprog.c testlib.a -o testprog

the output of the program is given by

testprog initialized 2.0000000000e+01 cleaned up

Why are the constructors not executed if the library is linked dynamically?

I use the following versions

GNU ld (GNU Binutils; openSUSE 11.3) 2.20.0.20100122-6 gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292] (SUSE Linux)

Thank you in advance for your help!

Edited: 2011-04-13, 11:05

Thank you very much luxifer,

the document helped indirectly! The magic hint was that one should involve the linker through the compiler...

gcc -fPIC testlib.c -shared -Wl,-soname,libtest.so -o libtest.so

works!!!

like image 686
rd478qx Avatar asked Apr 13 '11 08:04

rd478qx


1 Answers

Gcc's constructor handling is not the same thing as the ELF constructor handling, rather, it sits on top of it. To work, you need to link in the glue code that is provided in gcc's startup files.

The easiest way to do that is to link using gcc:

gcc -shared -o testlib.so testlib.o
like image 191
Simon Richter Avatar answered Nov 06 '22 18:11

Simon Richter