Resolving symbols error

From RidgeRun Developer Wiki


Introduction

In this wiki, you will get a brief explanation of dynamic libraries as well as how to resolve errors related to symbols.

What is dynamic linking?

Dynamic linking lets the program find the libraries required to execute the program. When a program is compiled and the headers are in another location, you can include it by providing the location of this library.

It is important to notice that when the LD_LIBRARY_PATH changes, the application will search the libraries in this location even though using the embed linking it's stated to search in other paths.

To check if the binary is finding the required libraries you can use the tool "ldd".

With this tool, you can know if it can find or not the libraries to execute the program.

Why does the order of the libraries affect when doing static linking?

On the contrary side of dynamic linking where the compiler will search for the libraries that satisfy each symbol, static linking will require looking first at the dependent libraries and finally the libraries that satisfy these symbols.

For example, the next .c will require the math library to handle the square function if you provide the following order in the compiler it will fail cause it won't find the library.

$ gcc -Wall -lm calc.c -o calc    (incorrect order)
main.o: In function `main':
main.o(.text+0xf): undefined reference to `sqrt'

While the correct order would be:

$ gcc -Wall calc.c -lm -o calc   (correct order)

LD_PRELOAD Trick

Using the LD_PRELOAD you can force the system to find shared libraries when it can't find them do to an error with the linking.

By this LD_PRELOAD is possible to change the order of the linking search of the application.

Take the next example.

ldd /usr/bin/pigz
	linux-vdso.so.1 (0x00007ffd559d7000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa48bcc1000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa48bc9e000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fa48bc82000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa48ba90000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fa48c065000)

After using LD_PRELOAD

LD_PRELOAD=/data/preload/lib/libz.so.1.2.7 ldd /usr/bin/pigz 
	linux-vdso.so.1 (0x00007ffc1d9c4000)
	/data/preload/lib/libz.so.1.2.7 (0x00007f33877d9000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3387674000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3387651000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f338745f000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f3387a32000)

You can see the change of the dependency for libz.so.1.2.7 after using the LD_PRELOAD, where it was after the libpthread.so.0 before.

Symbol not found

When you find this message, the problem could be related to the order of the libraries, so if you want to check this error you can proceed first with the next command.

 ldd

If you do not find the library then check the specific symbol in your library

 nm -D

Finally, check if all the dependencies are resolved in the correct order and then change the linker order as explained before.

Further Reading

References

What is LDD_PRELOAD_TRICK: https://www.baeldung.com/linux/ld_preload-trick-what-is

Linking order of libraries: https://www.linuxtopia.org/online_books/an_introduction_to_gcc/gccintro_18.html



For direct inquiries, please refer to the contact information available on our Contact page. Alternatively, you may complete and submit the form provided at the same link. We will respond to your request at our earliest opportunity.


Links to RidgeRun Resources and RidgeRun Artificial Intelligence Solutions can be found in the footer below.