Bibliothèque Dyanamic reliant par RTLD_LAZY

J’essaie de trouver la différence entre les drapeaux RTLD_NOW et RTLD_LAZY. Ma question est de savoir pourquoi RTLD_LAZY charge la bibliothèque dont je n’ai jamais référencé la fonction.

J’ai créé un fichier dlrun.c

#include "stdio.h" #include "dlfcn.h" main() { void * ptr; void (*fptr)(void); printf("\nMy ID is- %d \n",getpid()); getchar(); ptr = dlopen("./fun5.so", RTLD_NOW); if(ptr==NULL) printf("failed to open fun5.so"); else { printf("I got fun5.so"); fptr= dlsym(ptr,"fun5"); getchar(); fptr(); printf("end of fun5"); dlclose(ptr); } } 

le fichier suivant fun5.c as

 #include "stdio.h" void fun2(void); void fun1(void); fun5() { printf("I am in fun5"); getchar(); fun1(); } fun() { getchar(); fun2(); } 

autre fichier fun1.c est

 #include "stdio.h" fun1() { printf("I am in fun1"); getchar(); } 

et le fichier fun2.c est

 #include "stdio.h" fun2() { printf("I am in fun2"); getchar(); } 

alors j’utilise des commandes

 gcc -c -fPIC -o fun1.o fun1.c gcc -c -fPIC -o fun2.o fun2.c gcc -c -fPIC -o fun5.o fun5.c gcc -shared -o fun1.so fun1.o gcc -shared -o fun2.so fun2.o gcc -shared -o fun5.so fun5.o ./fun1.so ./fun2.so gcc dlrun.c -o run -ldl ./run 

maintenant je veux vérifier quelles bibliothèques sont chargées par

 cd /proc/ vi maps 

Ici, il semblerait qu’avant l’appel fun5.so, aucun librairie non-standard n’a été chargé et après avoir appelé la fonction fun5, tous les fichiers fun5.so, fun1.so et fun.2.so sont chargés selon l’attente. so et fun1.so devrait être chargé parce que je n’ai jamais appelé fun () et fun2 (), mais en fait, fun2.so charge aussi.où est-ce que je me trompe? Ai-je tort de créer fun5.so? Si oui, comment devrais-je le créer?

Merci

L’exemple suivant devrait le rendre très clair:

libtest.so:

 void bar(); void foo() { bar(); } 

_

 $> nm libtest.so 000085d0 a _DYNAMIC 000086b0 a _GLOBAL_OFFSET_TABLE_ w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable w _Jv_RegisterClasses 000005c0 r __FRAME_END__ 000085cc d __JCR_END__ 000085cc d __JCR_LIST__ 000086e0 d __TMC_END__ 000086e4 B __bss_end__ 000086e0 B __bss_start 000086e0 B __bss_start__ w __cxa_finalize@@GLIBC_2.4 000004f8 t __do_global_dtors_aux 000085c8 t __do_global_dtors_aux_fini_array_entry 000086dc d __dso_handle 000086e4 B __end__ 000085c4 t __frame_dummy_init_array_entry w __gmon_start__ 000086e4 B _bss_end__ 000086e0 D _edata 000086e4 B _end 000005b8 T _fini 000003e0 T _init U bar 00000424 t call_weak_fn 000086e0 b completed.8847 00000448 t deregister_tm_clones 000005a8 T foo 00000560 t frame_dummy 0000049c t register_tm_clones 

main.c (flag == RTLD_LAZY):

 #include  #include  int main(int argc, char **argv) { void *lib = dlopen("./libtest.so", RTLD_LAZY); if (!lib) { printf("error: %s\n", dlerror()); return 0; } int (*a)() = dlsym(lib, "foo"); printf("a: %p\n", a); (*a)(); dlclose(lib); return 1; } $> ./main.c a: 0xb6e225a8 ./main: symbol lookup error: ./libtest.so: undefined symbol: bar 

main.c (flag == RTLD_NOW):

 #include  #include  int main(int argc, char **argv) { void *lib = dlopen("./libtest.so", RTLD_NOW); if (!lib) { printf("error: %s\n", dlerror()); return 0; } int (*a)() = dlsym(lib, "foo"); printf("a: %p\n", a); (*a)(); dlclose(lib); return 1; } $> ./main.c error: ./libtest.so: undefined symbol: bar 

RTLD_LAZY signifie réellement résoudre les symboles paresseusement, ne pas charger les bibliothèques paresseusement. fun5.so dépend de ces deux bibliothèques afin qu’elles soient chargées lorsque fun5.so est chargé.

La ligne:

 gcc -shared -o fun5.so fun5.o ./fun1.so ./fun2.so 

nous dit que fun5.so dépend explicitement de fun1.so et fun2.so , c’est pourquoi vous voyez ce comportement.