I am trying to find the differance between RTLD_NOW and RTLD_LAZY flags. My query is why RTLD_LAZY loading the library whose function I've never referanced.
I have created a dlrun.c file
#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);
}
}
the next file fun5.c as
#include "stdio.h"
void fun2(void);
void fun1(void);
fun5()
{
printf("I am in fun5");
getchar();
fun1();
}
fun()
{
getchar();
fun2();
}
other file fun1.c is
#include "stdio.h"
fun1()
{
printf("I am in fun1");
getchar();
}
and file fun2.c is
#include "stdio.h"
fun2()
{
printf("I am in fun2");
getchar();
}
then I use commands
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
now I want to check which libraries are loaded by
cd /proc/<pid>
vi maps
Here it looks that before fun5.so calling no nonstansard libray is loaded and after calling fun5 function all fun5.so,fun1.so and fun.2.so are loaded as per expectation.Now if I replace RTLD_NOW by RTLD_LAZY then only fun5.so and fun1.so should be loaded because I have never called fun() and fun2() , but actually fun2.so is also loading.so where am I wrong? Am I wrong at creating fun5.so? if so then how should I create it?
Thanks
Dynamic libraries are linked during the execution of the final executable. Only the name of the dynamic library is placed in the final executable. The actual linking happens during runtime, when both executable and library are placed in the main memory.
Dynamic linking from Assembler language programs in IBM OS/360 and its successors is done typically using a LINK macro instruction containing a Supervisor Call instruction that activates the operating system routines that makes the library module to be linked available to the program.
If the same library is loaded again with dlopen(), the same file handle is returned. The dl library maintains reference counts for library handles, so a dynamic library is not deallocated until dlclose() has been called on it as many times as dlopen() has succeeded on it.
Dynamic loading is a mechanism by which a computer program can, at run time, load a library (or other binary) into memory, retrieve the addresses of functions and variables contained in the library, execute those functions or access those variables, and unload the library from memory.
The following example should make it very clear:
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 <dlfcn.h>
#include <stdio.h>
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 <dlfcn.h>
#include <stdio.h>
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
actually means resolve symbols lazily, not load libraries lazily. fun5.so
depends on both of these libraries so they will be loaded when fun5.so
is loaded.
The line:
gcc -shared -o fun5.so fun5.o ./fun1.so ./fun2.so
tells us that fun5.so
explicitly depends on fun1.so
and fun2.so
, which is why you're seeing this behaviour.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With