Tuesday, January 31, 2012

Debugging load library path issues

Debugging load library path issues
If you get a problem with a library that can't find another, you should check the library's dependencies and make sure that the directory in which the missing library resides is part of the load library path.

One example of this problem, that I experienced recently, occurred when the Magick.so library was unable to open the libMagick.so.10 library. The error message was as follows:

Can't load '/usr/lib/perl5/site_perl/5.8.7/i686-linux/auto/Image/Magick/Magick.so' for module Image::Magick: libMagick.so.10: cannot open shared object file: No such file or directory at /usr/lib/perl5/5.8.7/i686-linux/DynaLoader.pm line 230. at (eval 113) line 1 Compilation failed in require at (eval 113) line 1. BEGIN failed--compilation aborted at (eval 113) line 1.
Find out library dependencies with ldd

The ldd command will check the dependencies of a library.

ldd /the/library/path/libWhatever.so
Using the above example problem:

username@localhost [~]# ldd /usr/lib/perl5/site_perl/5.8.7/i686-linux/auto/Image/Magick/Magick.so
libMagick.so.10 => not found
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x0099a000)
libz.so.1 => /usr/lib/libz.so.1 (0x00111000)
libtiff.so.3 => /usr/lib/libtiff.so.3 (0x00121000)
libjpeg.so.62 => /usr/lib/libjpeg.so.62 (0x00d54000)
libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x001f4000)
libSM.so.6 => /usr/X11R6/lib/libSM.so.6 (0x0016e000)
libICE.so.6 => /usr/X11R6/lib/libICE.so.6 (0x00910000)
libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x0039d000)
libXt.so.6 => /usr/X11R6/lib/libXt.so.6 (0x005bc000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x004cc000)
libm.so.6 => /lib/tls/libm.so.6 (0x00216000)
libc.so.6 => /lib/tls/libc.so.6 (0x00bda000)
libdl.so.2 => /lib/libdl.so.2 (0x00177000)
/lib/ld-linux.so.2 (0x002c2000)
You can see in that the libMagick.so.10 library was not found.

Locate the library with find or locate or slocate or by any other means

Find the location of the library that couldn't be found by ldd. The chances are that the library will be in a subdirectory of /usr. Continuing with the above example...

username@localhost [~]# find /usr -name "libMagick.so.10"
/usr/local/lib/libMagick.so.10
Add the library to the load library path with ldconfig

In the words of the man page, ldconfig will configure dynamic linker run time bindings. Add your missing library to the bindings with the following command:

ldconfig /path/to/add
For our libMagick example, this would be:

username@localhost [~]# ldconfig /usr/local/lib
You can see a list of librarys that are being used with the -p flag.

username@localhost [~]# ldconfig -p
907 libs found in cache `/etc/ld.so.cache'
libzvt.so.2 (libc6) => /usr/lib/libzvt.so.2
libzvt.so (libc6) => /usr/lib/libzvt.so
libzip.so (libc6, hwcap: 0x0001000000000000) => /opt/blackdown-jdk-1.4.2.03/jre/lib/i386/libzip.so
libz.so.1 (libc6) => /lib/libz.so.1
libz.so (libc6) => /lib/libz.so
libxslt.so.1 (libc6) => /usr/lib/libxslt.so.1
libxslt.so (libc6) => /usr/lib/libxslt.so
[...cut...]
If you want to make make the changes more permanent, so that you don't have to remember to specify the directory next time you run the command, you can add it to the /etc/ld.so.conf file, though different linux distributions manage this file in different ways.

Reference:
http://mindspill.net/computing/linux-notes/debugging-load-library-path-issues/

No comments: