Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how dynamic linking works on UNIX

Consider we have the following situation:

  • a program named program which depends dynamically on libfoo.so
  • libfoo.so that depends on nothing (well, it depends on libstdc++ and stuff but I guess we can omit that)

program runs perfectly.

Suddenly, libfoo codes changes, and some function now uses internally func_bar() a function that is provided by another library libbar.so.

libfoo.so is recompiled and now depends on libbar.so. program remains unchanged, it still depends only on libfoo.so.

Now when I execute program it complains that he can't find func_bar().

Here are my questions:

  • libfoo.so interface didn't change, only its implementation. Why does program have to explicitely link with libbar.so ?
  • Isn't the dependency tree recursive ? I would have think that since libfoo.so depends on libbar.so, libbar.so would have been automatically added to the dependency list of program, without recompilation. However, ldd program shows that it is not the case.

It seems weird that one has to recompile (relink) every binary that depends on some library everytime that library's dependencies change. What solutions do I have here to prevent this ?

like image 612
ereOn Avatar asked Nov 05 '10 16:11

ereOn


People also ask

How does dynamic linking work Linux?

Dynamic linking is a two-step process that relies on accessing the addresses of code. The first step occurs at compilation. When a file is compiled with a dynamic library, instead of copying the actual object code contained in the library, the linker simply scans the code contained and checks for missing symbols.

What is dynamic linking Unix?

Dynamic linking is the most common method, especially on Linux systems. Dynamic linking keeps libraries modular, so just one library can be shared between any number of applications. Modularity also allows a shared library to be updated independently of the applications that rely upon it.

How is dynamic linking done?

In the dynamic linking approach, the linker does not copy the routines into the executables. It takes note that the program has a dependency on the library. When the program actually executes, the linker binds the function calls in the program to the shared library present in the disk.

What is dynamic linker in Linux?

In computing, a dynamic linker is the part of an operating system that loads and links the shared libraries needed by an executable when it is executed (at "run time"), by copying the content of libraries from persistent storage to RAM, filling jump tables and relocating pointers.


1 Answers

The problem arises when you have not linked libfoo.so against libbar. When you are compiling an executable, by default the linker will not let you leave undefined references. However, when you're compiling a shared library, it will - and it will expect them to be satisfied at link time. This is so that libfoo can use functions exported by program itself - when you try to run it, the dynamic linker is expecting func_bar() to be supplied by program. The problem is illustrated like so:

(foo.c is selfcontained)

export LD_RUN_PATH=`pwd` gcc -Wall -shared foo.c -o libfoo.so gcc -Wall -L. p.c -lfoo -o p 

At this point, ./p runs correctly, as you would expect. We then create libbar.so and modify foo.c to use it:

gcc -Wall -shared bar.c -o libbar.so gcc -Wall -shared foo.c -o libfoo.so 

At this point, ./p gives the error you describe. If we check ldd libfoo.so, we notice that it does not have a dependency on libbar.so - this is the error. To correct the error, we must link libfoo.so correctly:

gcc -Wall -L. -lbar -shared foo.c -o libfoo.so 

At this point, ./p again runs correctly, and ldd libfoo.so shows a dependency on libbar.so.

like image 180
caf Avatar answered Sep 30 '22 19:09

caf