Shared Library Linking Problems

From: Danny Diaz (ddiaz_at_gehennom.dot.net)
Date: 08/27/03

  • Next message: David Schwartz: "Re: Allocating Page Aligned Memory in User Space"
    Date: Wed, 27 Aug 2003 21:39:47 +0000 (UTC)
    
    

    I'm wondering if some behavior I am experiencing is "expected" or not.
    What I am attempting to do is create some shared libraries with 2 things
    in mind; 1) I want to share a global variable from the app with a
    library, and 2) I want to share some global functions from those
    libraries. For the global variable, I label the variable in my
    dll's as "extern". For the functions, I am well aware that all
    global functions within shared libraries are exported by default.

    Ok, so, all is good until I get around to linking the shared library. In
    the first case, I use the -Bsymbolic option in my linking step. With
    the -Bsymbolic, I find that the application and the shared library have
    seperate copies of the global variable; what gets set in one does not
    get set in the other. Also, functions behave as I would like them to
    behave: if LibA has a function called FOO, and libB has a function
    called FOO, libA will call his own FOO and libB will call his own FOO
    and the application will call whichever one was linked first if a call
    to FOO was made.

    The global variable issue killed me, so I used -Bgroup instead of
    -Bsymbolic. Now the global variables are exactly in sync; there aren't
    multiple copies of the variables any more. However, functions went all
    to hell. Now, no matter if LibA has a FOO function or not, LibA
    will call LibB's foo if it was linked first. This is very bad, you
    cannot guarantee any more that a function will call another function in
    the same library FIRST before looking at the global symbol table.

    So, My question is this: Is the behavior I have explained "expected" or
    is it a bug? And secondly, does anyone know of a way to get the global
    variable behavior of -Bgroup and the exported symbol functionality of
    -Bsymbolic?

    I have included some source code to help you understand my problem
    better. Save the code snippets to the named files, and execute one of
    the scripts to compile and run with the appropriate link option. I'd
    appreciate all of your input!

    NOTE: This works in gcc 3.2.2, I have not tried to get it to work in,
    say, gcc 2.9.x.

    ------ FILE: dllTestA.c ------
    #include <stdio.h>
    #include "dllTestA.h"

    int ibsta = 0;

    int foo( void ) {
       printf( "in libA::foo\n" );
       return 0;
    }
    int mylibA(int ibstaValue) {
       printf("in mylibA\n");
       printf("Setting ibsta to %d, ibsta addr: %p\n", ibstaValue, &ibsta);
       ibsta = ibstaValue;
       printf("Calling Foo... ");
       foo();
       return 0;
    }
    ------ END OF FILE -----------

    ------ FILE: dllTestB.c ------
    #include <stdio.h>
    #include "dllTestB.h"

    int ibsta = 0;

    int foo( void ) {
       printf( "in libB::foo\n" );
       return 0;
    }
    int mylibB(int ibstaValue) {
       printf("in mylibB\n");
       printf("Setting ibsta to %d, ibsta addr: %p\n", ibstaValue, &ibsta);
       ibsta = ibstaValue;
       printf("Calling Foo... ");
       foo();
       return 0;
    }
    ------ END OF FILE -----------

    ------ FILE: dllTestA.h ------
    #ifndef ___libA_h___
    #define ___libA_h___

    extern int ibsta;
    int mylibA(int inibsta);

    #endif
    ------ END OF FILE -----------

    ------ FILE: dllTestB.h ------
    #ifndef ___libB_h___
    #define ___libB_h___

    extern int ibsta;
    int mylibB(int inibsta);

    #endif
    ------ END OF FILE -----------

    ------ FILE: main.c ------
    #include <stdio.h>
    #include "dllTestA.h"
    #include "dllTestB.h"

    int main()
    {
       mylibA(0x130);
       mylibB(0x130);
       printf("in main\n");
       printf("ibsta: %d, addr: %p\n", ibsta, &ibsta);
       printf("Calling Foo from Main... ");
       foo();
       return 0;
    }
    ------ END OF FILE -----------

    ------ FILE: run-Bgroup.sh ------
    #!/bin/sh -v
    export LD_LIBRARY_PATH=.
    gcc -c -odllTestA.o -fPIC -g -O0 dllTestA.c
    gcc -c -odllTestB.o -fPIC -g -O0 dllTestB.c
    gcc -Wl,-Bgroup -shared -Wl,-soname,libdllTestAu.so.1 -o libdllTestAu.so.1.0.0 dllTestA.o
    gcc -Wl,-Bgroup -shared -Wl,-soname,libdllTestBu.so.1 -o libdllTestBu.so.1.0.0 dllTestB.o
    gcc -c -omain.o -g -O0 main.c
    gcc -omain main.o libdllTestBu.so.1.0.0 libdllTestAu.so.1.0.0
    ln -sf libdllTestAu.so.1.0.0 libdllTestAu.so.1
    ln -sf libdllTestBu.so.1.0.0 libdllTestBu.so.1
    ./main
    # *** NOTE: with -Bgroup in the link line, the main, libdllTestAu.so.1
    # *** and libdllTestBu.so.1 has one instance of the libsta
    # *** variable, as intended, but there is only one instance of
    # *** foo().
    ------ END OF FILE -----------

    ------ FILE: run-Bsymbolic.sh ------
    #!/bin/sh -v
    export LD_LIBRARY_PATH=.
    gcc -c -odllTestA.o -fPIC -g -O0 dllTestA.c
    gcc -c -odllTestB.o -fPIC -g -O0 dllTestB.c
    gcc -Wl,-Bsymbolic -shared -Wl,-soname,libdllTestAu.so.1 -o libdllTestAu.so.1.0.0 dllTestA.o
    gcc -Wl,-Bsymbolic -shared -Wl,-soname,libdllTestBu.so.1 -o libdllTestBu.so.1.0.0 dllTestB.o
    gcc -c -omain.o -g -O0 main.c
    gcc -omain main.o libdllTestBu.so.1.0.0 libdllTestAu.so.1.0.0
    ln -sf libdllTestAu.so.1.0.0 libdllTestAu.so.1
    ln -sf libdllTestBu.so.1.0.0 libdllTestBu.so.1
    ./main
    # *** NOTE: with -Bsymbolic in the link line, the main, libdllTestAu.so.1
    # *** and libdllTestBu.so.1 have multiple instances of the libsta
    # *** variable, but there are multiple instances of foo() - and
    # *** they are called correctly within their libraries.
    ------ END OF FILE -----------

    Thanks!
    -Danny

    -- 
    Danny Diaz         | "Don't you try to outweird me, 
    texasdiaz          |  I get stranger things than you
    @austin.rr.com     |  free in my breakfast cereal." - BZ
    Confidence is what you had before you understood the situation.
    

  • Next message: David Schwartz: "Re: Allocating Page Aligned Memory in User Space"

    Relevant Pages

    • Shared Library Linking Problems
      ... What I am attempting to do is create some shared libraries with 2 things ... called FOO, libA will call his own FOO and libB will call his own FOO ... Now the global variables are exactly in sync; ... int foo(void) { ...
      (comp.os.linux.development.apps)
    • Re: Detecting Reads of Global Uninitialized Variables
      ... The language guarantees that an int will be an int, ... The language guarantees the behavior for global variables, and you do not believe it. ... Somewhere there's a foo_initialize() function that sets up the foo subsystem, setting `foo_count' and presumably building other data structures as well. ...
      (comp.lang.c)
    • How to return two values in a function?
      ... double *foo(double *x, int *ret) ... In foo, sz's value is computed during running. ... using global variables. ...
      (comp.lang.c)
    • Re: [C] strcat() question (ongoing)
      ... > At the machine level, yes, basically (depending on your definition ... We can only "PUT" data in / or assign data to variables such as an int or ... foo is an object? ... > house and look on the microwave. ...
      (alt.comp.lang.learn.c-cpp)
    • Re: call of variadic function
      ... arguments that should be passed to this function are of type int. ... You call foo with more arguments than are ... which is the standard way to access arguments of a variadic function ... Here the else clause of my sentence specifies one of the numerous non- ...
      (comp.lang.c)