LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   __attribute__ ((weak)) suddenly stops working / starts working (http://www.linuxquestions.org/questions/programming-9/__attribute__-weak-suddenly-stops-working-starts-working-577174/)

ta0kira 08-15-2007 12:03 AM

__attribute__ ((weak)) suddenly stops working / starts working
 
I am progressively building a program which has 7 or so very similar libraries which load commands. About 3 have the load functions written and for all of them I have default "weak" definitions. Just today they started to cover the real definitions in some cases but not in others. Here is the basic layout:
Code:

[command lib X]]]]---------+  +-->[using lib 1]------------->[program type 1]
  load function X*        |  |    load function X (call)
                          +---+
                          |  |
[other lib]----------------+  +-->[using lib 2]------------->[program type 2]
  load function X (weak)            load function X (call)

*may or may not be defined

I always place the library with the real definition first when linking, but what's been happening with arbitrary changes to unrelated files is the weak definition covers the real one in the second lib but never the first (always used independently of each other.) If I comment out the weak definitions for those which are defined I don't have the problem, which indicates to me that the problem is just linking semantics. The makefiles haven't changed at all since they were working and all function definitions stayed the same, in the same files. I changed a few typedefs, but none that affect the function prototypes. Some other arbitrary changes restore the correct behavior, though, but not reliably.

Am I erroneously relying on this attribute, or is there a specific way you have to use it? It's worked for several months so far, and my diff output shows nothing to indicate that this should happen. Thanks.
ta0kira

jim mcnamara 08-15-2007 09:01 AM

I must be missing something. When you emit a weak symbol it allows the calling program to override the symbol at run-time.

weak symbols are declared that way in the calling procedure. Yours seem to be the libraries.
Or are you calling other libraries' modules with the same symbol name? In that case, call dld to force symbol definition from a specific library at runtime. If that's what you are doing -- what amounts to symbol overloading.

ta0kira 08-15-2007 10:11 AM

You don't have to define a symbol as weak for the final program to override it if the symbol is in a shared library. That entirely depends on link order, though. Basically what I'm doing is declaring the load functions in each of the command library headers and a separate library provides weak definitions (among many other things.) If I define the load function in a command library I expect it to override the weak symbol when loaded at run time, which it has until now. Example:
Code:

/* command.h */

void load();

Code:

/* command.c */
#include "command.h"
#include <stdio.h>

void load() { printf("defined\n"); } /* sometimes defined, sometimes not */

Code:

> gcc -fPIC -shared command.c -o libcommand.so
Code:

/* additional.c */
#include "command.h"
#include <stdio.h>

void __attribute__ ((weak)) load() { printf("default\n"); }

Code:

> gcc -fPIC -shared additional.c -o libadditional.so
Code:

/* user.h */

void load_everything();

Code:

/* user.c */
#include "command.h"

void load_everything() { load(); }

Code:

> gcc -fPIC -shared user.c ./libcommand.so ./libadditional.so -o libuser.so
Code:

/* userprogram.c */
#include "user.h"

int main()
{
    load_everything();
}

Code:

> gcc userprogram.c -Xlinker -rpath-link=. ./libuser.so -o userprogram
> ./userprogram

> gcc -fPIC -shared user.c ./libadditional.so -o libuser.so
> ./userprogram

The idea is that the command libraries can be excluded from the user library at link time by just not linking to them, or by not defining the load function while it's in development.

The opposite of this attribute would be "protected" visibility, but that only works for calls within the same library as the protected definition, so that won't work.
ta0kira

PS I think it has to do with dynamic load order. I think the real command lib depends on the additional lib, so it loads that lib before itself, even though the additional lib comes after it when linking the user lib.

ta0kira 08-15-2007 11:31 AM

Ok, here is what I think is happening. The library corresponding to "using lib 2" somehow has a dependency in the additional lib, so that lib is loaded before the command libs. "using lib 1" has no direct dependency to the additional lib, so it's only loaded as needed after the command libs are loaded. I'll track down that dependency later and see if I'm right.
ta0kira


All times are GMT -5. The time now is 05:19 PM.