[轉載請註明出處] http://kezeodsnx.pixnet.net/blog
作者: kezeodsnx
偶爾會遇到一個狀況,執行一個binary時,發現少了某個library,如下:
root@user-ubuntu:/lib# nano
nano: error while loading shared libraries: libncursesw.so.5: cannot open shared object file: No such file or directory
通常會用一下ldd看看狀況如何:
root@user-ubuntu:/lib# ldd /bin/nano
linux-gate.so.1 => (0xb8042000)
libncursesw.so.5 => not found
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eb6000)
/lib/ld-linux.so.2 (0xb8028000)
發現 libncursesw.so.5找不到。經過一翻google,find之後,發現libncursesw.so.5並不在ld.so的search path (/lib, /usr/lib)裡,而是莫名其妙的跑到了/usr/local/lib下。此時,把/usr/local/lib加入ld.so的search path: export LD_LIBRARY_PATH=/usr/local/lib可解決這個問題:
root@user-ubuntu:/lib# export LD_LIBRARY_PATH=/usr/local/lib
root@user-ubuntu:/opt# ldd /bin/nano
linux-gate.so.1 => (0xb7f3b000)
libncursesw.so.5 => /usr/local/lib/libncursesw.so.5 (0xb7ee4000)
這就是LD_LIBRARY_PATH: 一個環境變數,讓runtime linker (ld.so)去多找LD_LIBRARY_PATH所指定的路徑。看來似乎很方便,但也有其限制: 當setuid/setgid (when set,若other group有執行權限,當該group的member執行此binary時,即擁有owner的權限)set時,LD_LIBRARY_PATH會被ignore。
user@user-ubuntu:/lib$ sudo chmod a+s /bin/nano
user@user-ubuntu:/lib$ export LD_LIBRARY_PATH=/usr/local/lib
user@user-ubuntu:/lib$ nano
nano: error while loading shared libraries: libncursesw.so.5: cannot open shared object file: No such file or directory
這當然是為了安全的理由。因此,LD_LIBRARY_PATH的用途通常為更新新版的library前,測試一下,或是為了某些原因想要將lib換位置。因此,有人建議在開發時可使用,但若是一個product,就很可能會發生問題。更好的做法是在compile time時,加上-R指定其run time的路徑,比如說在Makefile裡加上:
export LDFLAGS="-R/usr/local/lib"
在runtime使用LD_LIBRARY_PATH也有一些performance的考量,因為search也是需要時間。
Reference:
留言列表