So, I have two versions of a shared library: the stable version, which is installed under ~/builds/libfoo
and a development version, which lives in the source tree ~/src/libfoo
. I have just compiled a new version of the source and I want to test it, so I run make test
.
Crash. Uh oh.
Let’s try the static version of the library.
OK. That works.
Maybe it’s picking up the wrong version of the shared library. I set LD_LIBRARY_PATH=~/src/libfoo
and run make test
.
Crash. Damn.
make test
is, after a fashion, running ./bin/test
. Let’s try that ourselves.
That works. Huh?!
$ export LD_LIBRARY_PATH=/home/chris/src/libfoo/lib $ ldd ./bin/test ... libfoo.so.1 => /home/chris/builds/libfoo/lib/libfoo.so.1.0 ...
Do you trust export
?
$ LD_LIBRARY_PATH=/home/chris/src/libfoo/lib ldd ./bin/test ... libfoo.so.1 => /home/chris/builds/libfoo/lib/libfoo.so.1.0 ...
Do you trust ldd
?
$ /lib/ld-linux.so.2 --list ./bin/test ... libfoo.so.1 => /home/chris/src/libfoo/lib/libfoo.so.1.1 ...
Damn you ldd
. I knew it was you all along.
So, what happened? Some time ago, in the pursuit of a PATH
-related bug, I moved all my shell path-munging preferences—including adding ~/builds/libfoo/lib
to LD_LIBRARY_PATH
—to .bash_env
. .bash_env
gets read every time that a new shell is created, including—wait for it—when running shell scripts or make
. (ldd
is a shell script. ld-linux.so.2
isn’t.) In other words, the line
export LD_LIBRARY_PATH=~/builds/libfoo/lib:$LD_LIBRARY_PATH
in my .bash_env
was clobbering all of my attempts to set LD_LIBRARY_PATH
at the command line.
The moral of the story? Munge LD_LIBRARY_PATH
in your .bash_profile
. And never trust ldd
.
Absolutely right. ldd is bad. Use LD_TRACE_LOADED_OBJECTS=1 ./program instead and let the linker show you exactly what’s happening. Or just take out the big guns and use strace. I have more info about library paths that you may like.
Comment by enchildfone — March 22, 2010 @ 11:53 pm