Dissecting Shared Libraries
By Peter Seebach2005-03-22
Modifying the dynamic linker search path
When linking a program, you can specify additional paths to search at runtime. In gcc the syntax is -Wl,-R/path. If the program is already linked, you can also change this behavior by setting the environment variable LD_LIBRARY_PATH. Usually this is needed only if your application wants to search paths that aren't part of the system-wide default, a rare case for most Linux systems. In theory, the Mozilla people could have distributed a binary compiled with that path set, but they preferred to distribute a wrapper script that sets the library path appropriately before launching the executable.
Setting the library path can provide a workaround in the rare case where two applications require incompatible versions of a library. A wrapper script can be used to have one application search in a directory using the special version of the library it requires. Hardly an elegant solution, but in some cases it's the best you can do.
If you have a compelling reason to add a path to many programs, you can also change the system's default search path. The dynamic linker is controlled through /etc/ld.so.conf, which contains a list of directories to search by default. Any paths specified in LD_LIBRARY_PATH will be searched before the paths listed in ld.so.conf, so users can override these settings.
Most users have no reason to change the system default library search paths; generally the environment variable is a better match for likely reasons to change the search path, such as linking with libraries in a toolkit or testing programs against a newer version of a library.
Using ldd
One useful tool for debugging shared library problems is ldd. The name derives from list dynamic dependencies. This program looks at a given executable or shared library and figures out what shared libraries it needs to load and which versions would be used. The output looks like this:
Listing 1. Dependencies of /bin/sh
$ ldd /bin/sh
linux-gate.so.1 => (0xffffe000)
libreadline.so.4 => /lib/libreadline.so.4 (0x40036000)
libhistory.so.4 => /lib/libhistory.so.4 (0x40062000)
libncurses.so.5 => /lib/libncurses.so.5 (0x40069000)
libdl.so.2 => /lib/libdl.so.2 (0x400af000)
libc.so.6 => /lib/tls/libc.so.6 (0x400b2000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
It can be a little surprising to find out how many libraries a "simple" program uses. It's probably the case that libhistory is the one calling for libncurses. To find out, we can just run another ldd command:
Listing 2. Dependencies of libhistory
$ ldd /lib/libhistory.so.4
linux-gate.so.1 => (0xffffe000)
libncurses.so.5 => /lib/libncurses.so.5 (0x40026000)
libc.so.6 => /lib/tls/libc.so.6 (0x4006b000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
In some cases, an application may need extra library paths specified. For instance, the first few lines of an attempt to run ldd on the Mozilla binary came out like this:
Listing 3. Result of ldd for items not in search path
$ ldd /opt/mozilla/lib/mozilla-bin
linux-gate.so.1 => (0xffffe000)
libmozjs.so => not found
libplds4.so => not found
libplc4.so => not found
libnspr4.so => not found
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x40037000)
Why aren't these libraries found? Because they're not in the usual search path for libraries. In fact, they're found in /opt/mozilla/lib, so one solution would be to add that directory to LD_LIBRARY_PATH.
Another option is to set the path to . and run ldd from that directory, although this is a little more dangerous -- putting the current directory in your library path is just as potentially treacherous as putting it in your executable path.
In this case, it's pretty clear that adding the directory these are in to the system-wide search path would be a bad idea. Nothing but Mozilla needs these libraries.
Tutorial Pages:
» Get to know your shared library
» How shared libraries work
» Compatibility's not just for relationships
» To debug, first you must know how to compile
» Modifying the dynamic linker search path
» Linking Mozilla
» Learning more about shared libraries
» Resources
First published by IBM DeveloperWorks
| Related Tutorials: » How to Install PHP 5 on Linux » How to Install Apache 2 on Linux » How to Install MySQL 5.0 on Linux » SMB Caching » Mound --Bind » Tar Wild Card Interpretation |
