pqy@localhost ~/src/test/a $ cat m.c
#include <stdio.h>
int aaaaa __attribute__ ((weak)) =8;
int main(void){
printf("%d\n", aaaaa);
return 0;
}
pqy@localhost ~/src/test/a $ cat lib.c
int aaaaa = 5;
pqy@localhost ~/src/test/a $ gcc lib.c -fPIC -shared -o libb.so;gcc m.c -o m -L. -lb -Wl,-rpath=$PWD;./m
8
Above is my code and test result. I am confused why it does not work as expected.
Also try function, not work ether. Below is the test result.
pqy@localhost ~/src/test/a $ cat lib.c
int fun() {
return 5;
}
pqy@localhost ~/src/test/a $ cat m.c
#include <stdio.h>
__attribute__((weak)) int fun() {
return 8;
}
int main(void){
printf("%d\n", fun());
return 0;
}
pqy@localhost ~/src/test/a $ gcc lib.c -fPIC -shared -o libb.so;gcc m.c -O0 -o m -L. -lb -Wl,-rpath=$PWD;./m
8
pqy@localhost ~/src/test/a $ ldd m
linux-vdso.so.1 (0x00007ffd819ec000)
libb.so => /home/pqy/src/test/a/libb.so (0x00007f7226738000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7226533000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7226744000)
pqy@localhost ~/src/test/a $
At bottom what you have observed here is just the fact that the linker will not resolve a symbol dynamically if it can resolve it statically. See:
main.c
dynamic_foo.c
static_foo.c
Compile the sources so:
Make a shared library:
And link a program:
It runs like:
So
fooandneed_static_foowere statically resolved to the definitions fromstatic_foo.oand the definition offoofromlibfoo.sowas ignored, despite the fact thatlibfoo.sowas needed and provided the definition ofneed_dynamic_foo. It makes no difference if we change the linkage order to:It also makes no difference if we replace
static_foo.cwith:static_weak_foo.c
Compile that and relink:
Although the definition of
fooinstatic_weak_foo.cis now declared weak, the fact thatfoocan be statically resolved to this definition still preempts any need to resolve it dynamically.Now if we write another source file containing another strong definition of
foo:static_strong_foo.c
and compile it and link as follows:
we see:
Now,
libfoo.sostill provides the definition ofneed_dynamic_foo, because there is no other;static_weak_foo.ostill provides the only definition ofneed_static_foo, and the definition offooinlibfoo.sois still ignored because the symbol can be statically resolved.But in this case there are two definitions of
fooin different files that are available to resolve it statically: the weak definition instatic_weak_foo.oand the strong definition instatic_strong_foo.o. By the linkage rules that you are familiar with, the strong definition wins.If both of these statically linked definitions of
foowere strong, there would of course be a multiple definition error, just like:in which the dynamic definition in
libfoo.soplays no part. So you can be guided by this practical principle: The rules you are familiar with for arbitrating between weak and strong definitions of the same symbol in a linkage only apply to rival definitions which would provoke a multiple definition error in the absence of theweakattribute.