Note that there are some explanatory texts on larger screens.

plurals
  1. POLinux shared library global constructors interdependency
    primarykey
    data
    text
    <p>Operating system Centos 5.6 i686 2.6.18-53.1.4.el5vm.<BR> gcc version 4.1.2 20080704 (Red Hat 4.1.2-48) <BR> ld version 2.17.50.0.6-6.el5 20061020 <BR><BR> I compile in this way:<BR> gcc -c -fnon-call-exceptions -fexceptions -Wall -DUNICODE -D_UNICODE -D_REENTRANT -I. <br>and link this way:<br> gcc -lstdc++ -pthread -ldl -lrt --no-relocate -Wl,-rpath,$SO_DIR -L$SO_DIR $LIBRARIES <br><br> I have 3 libraries and an executable: A.so, B.so, C.so, ElfExec<BR> B.so depends on A.so. C.so depends on B.so.<br> In code A.so has a header through which it exposes functionality A.h, B.so in code has a B.h header which includes A.h and B functionality. C.so in code includes B.h.<br> A.h has defined a static variable K of a type that can be used if and only if a static memory manager from A.so is initialized. Variable K is directly defined in A.h, in the header, because of this its initialization is propagated in the global constructors of all objects composing B.so and C.so.</p> <p>I link everything like this:<BR> gcc "ALL B MODULES" -lstdc++ -pthread -ldl -lrt --no-relocate -Wl,-rpath,$SO_DIR -L$SO_DIR A.so <BR> gcc "ALL C MODULES" -lstdc++ -pthread -ldl -lrt --no-relocate -Wl,-rpath,$SO_DIR -L$SO_DIR B.so <BR> gcc "ALL ElfExec MODULES" -lstdc++ -pthread -ldl -lrt --no-relocate -Wl,-rpath,$SO_DIR -L$SO_DIR C.so <BR> I also tried: <BR> gcc "ALL ElfExec MODULES" -lstdc++ -pthread -ldl -lrt --no-relocate -Wl,-rpath,$SO_DIR -L$SO_DIR A.so B.so C.so <BR></p> <p>When run ElfExec gets a SIGSEGV because it tries to initialize the variable K before the static memory manager from A.so is initialized.<BR> This is because the global constructors from C.so are called before the ones from A.so. <br> If I make an application ElfExec2 that only need B.so <BR> gcc "ALL ElfExec1 MODULES" -lstdc++ -pthread -ldl -lrt --no-relocate -Wl,-rpath,$SO_DIR -L$SO_DIR B.so <BR> this works correctly.</p> <p>In the case of ElfExec1 the linker sees that global constructors from A.so are needed to be called first before the ones from B.so.<BR> This does not happed in the case of ElfExec.</p> <p>My solution is to link C.so like this: gcc "ALL C MODULES" -lstdc++ -pthread -ldl -lrt --no-relocate -Wl,-rpath,$SO_DIR -L$SO_DIR A.so B.so <BR> This puts a direct dependency in the C.so to A.so.</p> <p>Is there another way to tell the linker the order of global constructors calling?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload