Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux shared library that uses a shared library undefined symbol

Tags:

linux

gcc

shared

two shared libraries liba.so and libb.so. liba.so uses libb.so. All c files are compiled with -fPIC. Linking uses -shared. When we call dlopen on liba.so it cannot find symbols in libb.so...we get the "undefined symbol" error. We can dlopen libb.so with no errors. We know that liba is finding libb because we don't get a file not found error. We get a file not found error when we delete libb.so. We tried -lutil and no luck.

Any ideas????

oh yeah. gcc 4.1.2

update: We use rpath when linking liba so it can find libb.

ldd liba.so returns:

linux-gate.so.1 => (0xffffe000)  
libb.so => ./libb.so (0xf6ef9000)  <-------- LIBB 
libutil.so.1 => /lib/libutil.so.1 (0xf6ef5000)  
libdl.so.2 => /lib/libdl.so.2 (0xf6ef1000)  
libm.so.6 => /lib/libm.so.6 (0xf6ec9000)  
libpthread.so.0 => /lib/libpthread.so.0 (0xf6eb1000)  
librt.so.1 => /lib/librt.so.1 (0xf6ea8000)  
libc.so.6 => /lib/libc.so.6 (0xf6d62000)  
/lib/ld-linux.so.2 (0x007d0000)   

is it significat that there is no .# at the end of libb???

like image 409
johnnycrash Avatar asked Jun 07 '10 17:06

johnnycrash


People also ask

How do I find the symbol in an .so file?

The flag -g is used to show only exported symbols. Show activity on this post. Try adding -l to the nm flags in order to get the source of each symbol. If the library is compiled with debugging info (gcc -g) this should be the source file and line number.

What is an undefined symbol?

A symbol remains undefined when a symbol reference in a relocatable object is never matched to a symbol definition. Similarly, if a shared object is used to create a dynamic executable and leaves an unresolved symbol definition, an undefined symbol error results.

What is a Linux shared library?

Shared libraries are the most common way to manage dependencies on Linux systems. These shared resources are loaded into memory before the application starts, and when several processes require the same library, it will be loaded only once on the system. This feature saves on memory usage by the application.

How does Linux find shared libraries?

In Linux, shared libraries are stored in /lib* or /usr/lib*. Different Linux distributions or even versions of the same distribution might package different libraries, making a program compiled for a particular distribution or version not correctly run on another.


1 Answers

You can easily check where libb.so is expected to be with ldd command:

 $ ldd liba.so
    linux-gate.so.1 =>  (0xb77b0000)
    libb.so.1 => not found
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75b6000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7572000)
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb742b000)
    /lib/ld-linux.so.2 (0xb77b1000)

If it's not found, libb.so's path should be added to /etc/ld.so.conf or shell variable LD_LIBRARY_PATH.

Another way is setting rpath in the liba.so itself - it's basically hardcoding its path so when the binary is started the dynamic linker would know where to search for the shared libraries.

If rpath is not set it will first search in LD_LIBRARY_PATH, then the paths mentioned in /etc/ld.so.conf (or /etc/ld.so.conf.d/). After adding to ls.so.conf don't forget to execute /sbin/ldconfig

Dynamic linker searches the dependent shared libraries by their soname (if it's set) - if soname is not set (with -Wl,-soname,libb.so.1 for example), it will be searched by library's name.

Example: libb.so.1.0 is your actual library, having soname - libb.so.1. You would normally have the following files structure:

libb.so -> libb.so.1
libb.so.1 -> libb.so.1.0
libb.so.1.0

where libb.so and libb.so.1 are symlinks.

You usually link to libb.so, when building some application or other library, depending on libb.so.

gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L/libb/path -lb

When the application is started (or dlopen is executed - your case) - the dynamic linker will search for file with name libb.so.1 - the soname of dependent library, if the soname is set, not libb.so.

That's why you need that symlink libb.so.1, pointing to the actual library.

If you use ld.so.conf and ldconfig, it will create the symlink with soname's name, pointing to the library file, if this symlink is missing.

You can see ld-linux man page for more useful info.


If the library is found but some of the symbols are missing, try building libb.so with -Wl,--no-undefined option
gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2

It should give you an error if you missed to define some symbol.

like image 165
Dmitry Yudakov Avatar answered Oct 14 '22 04:10

Dmitry Yudakov