Rambles around computer science

Diverting trains of thought, wasting precious time

Fri, 23 Jan 2009

Library path strangenesses

It's about time I began sharing the hard-learnt arcane development knowledge I've managed to pick up. One of the most annoying “features” I've had to reverse-engineer is in the behaviour of Linux's dynamic linker, ld-linux. I have a lot of directories in my LD_LIBRARY_PATH environment variable.

srk31@font:~/scratch/kde$ echo 
/home/srk31/scratch/opt/lib:/home/srk31/scratch/kde/lib:/usr/lib/mysql:/usr/lib/opensync/:/usr/lib/o
pensync/formats/:/usr/lib/opensync/plugins/:/usr/lib/qt-3.3/lib:/usr/lib/wine/:/home/srk31/opt/lib:/
lib:/usr/lib 

They all get searched as you'd expect. Each directory is expanded to include searches for various architecture-specific variant subdirectories like tls, sse2, nosegneg etc.

srk31@font:~/scratch/kde$ LD_DEBUG=libs ldd bin/konsole 2>&1 | head
      5666:     find library=libtinfo.so.5 [0]; searching
      5666:      search path=/home/srk31/scratch/opt/lib/tls/i686/sse2/nosegneg:/home/srk31/scratch/
opt/lib/tls/i686/sse2:/home/srk31/scratch/opt/lib/tls/i686/nosegneg:/home/srk31/scratch/opt/lib/tls/
i686:/home/srk31/scratch/opt/lib/tls/sse2/nosegneg:/home/srk31/scratch/opt/lib/tls/sse2:/home/srk31/
scratch/opt/lib/tls/nosegneg:/home/srk31/scratch/opt/lib/tls:/home/srk31/scratch/opt/lib/i686/sse2/n

(snipped some -- view source for more)

osegneg:/home/srk31/opt/lib/i686/sse2:/home/srk31/opt/lib/i686/nosegneg:/home/srk31/opt/lib/i686:/ho
me/srk31/opt/lib/sse2/nosegneg:/home/srk31/opt/lib/sse2:/home/srk31/opt/lib/nosegneg:/home/srk31/opt
/lib            (LD_LIBRARY_PATH)
      5666:       trying file=/home/srk31/scratch/opt/lib/tls/i686/sse2/nosegneg/libtinfo.so.5
      5666:       trying file=/home/srk31/scratch/opt/lib/tls/i686/sse2/libtinfo.so.5
      5666:       trying file=/home/srk31/scratch/opt/lib/tls/i686/nosegneg/libtinfo.so.5

Notice that in my LD_LIBRARY_PATH, /usr/lib and lib are right at the end. Once I tried tweaking the ordering so that some paths came after these -- they were “backup” libraries I'd compiled myself in case the machine I was using didn't have them, but I wanted to pick up any local ones in preference. Unfortunately, this doesn't work. ld-linux will ignore all directories after the first directory it encounters that is part of the “system library path”.

srk31@font:~/scratch/kde$ LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} LD_DEBUG=libs ldd bin/konsole 2>&1 | head
      5687:     find library=libtinfo.so.5 [0]; searching
      5687:      search path=/usr/lib/tls/i686/sse2/nosegneg:/usr/lib/tls/i686/sse2:/usr/lib/tls/i68
6/nosegneg:/usr/lib/tls/i686:/usr/lib/tls/sse2/nosegneg:/usr/lib/tls/sse2:/usr/lib/tls/nosegneg:/usr
/lib/tls:/usr/lib/i686/sse2/nosegneg:/usr/lib/i686/sse2:/usr/lib/i686/nosegneg:/usr/lib/i686:/usr/li
b/sse2/nosegneg:/usr/lib/sse2:/usr/lib/nosegneg:/usr/lib                (system search path)
      5687:       trying file=/usr/lib/tls/i686/sse2/nosegneg/libtinfo.so.5
      5687:       trying file=/usr/lib/tls/i686/sse2/libtinfo.so.5
      5687:       trying file=/usr/lib/tls/i686/nosegneg/libtinfo.so.5
      5687:       trying file=/usr/lib/tls/i686/libtinfo.so.5
      5687:       trying file=/usr/lib/tls/sse2/nosegneg/libtinfo.so.5
      5687:       trying file=/usr/lib/tls/sse2/libtinfo.so.5
      5687:       trying file=/usr/lib/tls/nosegneg/libtinfo.so.5
      5687:       trying file=/usr/lib/tls/libtinfo.so.5

I have no idea why it does this, but would guess it's intended behaviour for some reason. It's annoying though.

Oh, and another gotcha relating to LD_LIBRARY_PATH is that if you're using gdb, it seems you must set solib-search-path to match your LD_LIBRARY_PATH, because gdb seems to ignore the latter (again, probably for some reason or other). And if you ever use a frontend to gdb, like DDD, that probably has its own setting too. There is so much fun to be had with these things.

[/devel] permanent link contact


Powered by blosxom

validate this page