[轉載請註明出處] 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:

LD_LIBRARY_PATH is not the answer

Why LD_LIBRARY_PATH is bad

LD_LIBRARY_PATH - just say no

kezeodsnx 發表在 痞客邦 PIXNET 留言(0) 人氣()