天天看點

ld錯誤 error while loading shared libraries 處理以及相關内容

1問題描述

在學習有關libpcap的内容時,參考了檔案《Programmingwith pcap》(連結:http://www.tcpdump.org/pcap.html),其中剛開始就遇到了問題,程式如下:

#include <stdio.h>      
#include <pcap.h>      
int main(int argc, char *argv[])      
{      
char *dev, errbuf[PCAP_ERRBUF_SIZE];      
dev = pcap_lookupdev(errbuf);      
if (dev == NULL) {      
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);      
return(2);      
}      
printf("Device: %s\n", dev);      
return(0);      
}      

問題如下:

[[email protected]]$ ls

lookup_dev  lookup_dev.c

[[email protected]]$ gcc -g -o lookup_dev -lpcap lookup_dev.c-L/usr/local/lib

[[email protected] pcap]$./lookup_dev

./lookup_dev: errorwhile loading shared libraries: libpcap.so.1: cannot open sharedobject file: No such file or directory

[[email protected]]$ ldd lookup_dev

       linux-vdso.so.1 =>  (0x00007fff66eea000)

       libpcap.so.1 => notfound

        libc.so.6=> /lib64/libc.so.6 (0x00000037e2800000)

       /lib64/ld-linux-x86-64.so.2 (0x00000037e2400000)

[[email protected]]$

2解決之道

2.1原因分析

原因1:共享庫不存在或安裝錯誤。

用rpm-qa  | grep -i libpcap指令檢查是否安裝了libpcap和libpcap-devel。

[[email protected]]$rpm -qa  | grep -ilibpcap

libpcap-0.9.4-15.el5

原因2:共享庫已經正确安裝,但程式按照預設共享庫路徑找不到該共享庫檔案。

加載共享庫因路徑出錯,肯定與ld有關,檢視連接配接器ld的内容。

連接配接器使用下面的搜尋路徑來定位需要的共享庫:

1.所有由'-rpath-link'選項指定的搜尋路徑.

2.所有由'-rpath'指定的搜尋路徑.'-rpath'跟'-rpath_link'的不同之處在于,由'-rpath'指定的路徑被包含在可執行檔案中,并在運作時使用,而'-rpath-link'選項僅僅在連接配接時起作用.它隻用于本地連接配接器.

3.在一個ELF系統中,如果'-rpath'和'rpath-link'選項沒有被使用,會搜尋環境變量'LD_RUN_PATH'的内容.它也隻對本地連接配接器起作用.

4.在SunOS上,'-rpath'選項不使用,隻搜尋所有由'-L'指定的目錄.

5.對于一個本地連接配接器,環境變量'LD_LIBRARY_PATH'的内容被搜尋.

6.對于一個本地ELF連接配接器,共享庫中的`DT_RUNPATH'和`DT_RPATH'操作符會被需要它的共享庫搜尋.如果'DT_RUNPATH'存在了,那'DT_RPATH'就會被忽略.

7.預設目錄,正常的,如'/lib'和'/usr/lib'.

8.對于ELF系統上的本地連接配接器,如果檔案'/etc/ld.so.conf'存在,這個檔案中有的目錄會被搜尋.

如果需要的共享庫沒有被找到,那連接配接器會發出一條警告資訊,并繼續執行連接配接.

共享庫路徑設定問題,如下:

1)如果共享庫檔案安裝到了/lib或/usr/lib目錄下,那麼需執行一下ldconfig指令

ldconfig指令的用途,主要是在預設搜尋目錄(/lib和/usr/lib)以及動态庫配置檔案/etc/ld.so.conf内所列的目錄下,搜尋出可共享的動态連結庫(格式如lib*.so*),進而建立出動态裝入程式(ld.so)所需的連接配接和緩存檔案.緩存檔案預設為/etc/ld.so.cache,此檔案儲存已排好序的動态連結庫名字清單.

2)如果共享庫檔案安裝到了/usr/local/lib(很多開源的共享庫都會安裝到該目錄下)或其它"非/lib或/usr/lib"目錄下,那麼在執行ldconfig指令前,還要把新共享庫目錄加入到共享庫配置檔案/etc/ld.so.conf中,如下:

[[email protected]]$ cat /etc/ld.so.conf

includeld.so.conf.d/*.conf

[[email protected]]$echo "/usr/local/lib" >> /etc/ld.so.conf

3)如果共享庫檔案安裝到了其它"非/lib或/usr/lib"目錄下, 但是又不想在/etc/ld.so.conf中加路徑(或者是沒有權限加路徑).那可以export一個全局變量LD_LIBRARY_PATH,然後運作程式的時候就會去這個目錄中找共享庫.

LD_LIBRARY_PATH的意思是告訴loader在哪些目錄中可以找到共享庫.可以設定多個搜尋目錄,這些目錄之間用冒号分隔開.比如安裝了一個mysql到/usr/local/mysql目錄下,其中有一大堆庫檔案在/usr/local/mysql/lib下面,則可以在.bashrc或.bash_profile或shell裡加入以下語句即可:

exportLD_LIBRARY_PATH=/usr/local/mysql/lib:$LD_LIBRARY_PATH

一般來講這隻是一種臨時的解決方案,在沒有權限或臨時需要的時候使用.

4)如果程式需要的庫檔案比系統目前存在的檔案版本低,可以做一個連結

比如:

errorwhile loading shared libraries: libncurses.so.4: cannot openshared

object file: No such file or directory

ls/usr/lib/libncu*

/usr/lib/libncurses.a  /usr/lib/libncurses.so.5

/usr/lib/libncurses.so  /usr/lib/libncurses.so.5.3

可見雖然沒有libncurses.so.4,但有libncurses.so.5,是可以向下相容的

建一個連結就好了

[[email protected]]$sudo ln -s /usr/local/lib/libpcap.so.1/usr/lib/libpcap.so.1

[[email protected]]$whereis libpcap.so.1

libpcap.so:/usr/lib/libpcap.so.1 /usr/local/lib/libpcap.so.1/usr/local/lib/libpcap.so

[[email protected]]$ ls -l /usr/lib/libpcap.so.1

lrwxrwxrwx 1 root root 27 Nov12 18:04 /usr/lib/libpcap.so.1 -> /usr/local/lib/libpcap.so.1

2.2正确結果

[[email protected]]$ldd lookup_dev

       linux-vdso.so.1 =>  (0x00007fff499ff000)

       libpcap.so.1 =>/usr/local/lib/libpcap.so.1 (0x00007fd8d3292000)

       libc.so.6 => /lib64/libc.so.6 (0x00000037e2800000)

       /lib64/ld-linux-x86-64.so.2 (0x00000037e2400000)

[[email protected]]$ sudo ldd lookup_dev

       linux-vdso.so.1 =>  (0x00007fff223ff000)

       libpcap.so.1 => /usr/local/lib/libpcap.so.1(0x00007f7e6671b000)

       libc.so.6 => /lib64/libc.so.6 (0x00000037e2800000)

       /lib64/ld-linux-x86-64.so.2 (0x00000037e2400000)

[[email protected]]$ readelf -d lookup_dev

Dynamic sectionat offset 0x900 contains 21 entries:

  Tag       Type                        Name/Value

 0x0000000000000001 (NEEDED)            Shared library:[libpcap.so.1]

 0x0000000000000001(NEEDED)            Shared library:[libc.so.6]

 0x000000000000000c (INIT)              0x400520

 0x000000000000000d (FINI)              0x4007c8

 0x000000006ffffef5 (GNU_HASH)          0x400240

 0x0000000000000005 (STRTAB)            0x4003b8

 0x0000000000000006 (SYMTAB)            0x400280

 0x000000000000000a (STRSZ)             155 (bytes)

 0x000000000000000b (SYMENT)            24 (bytes)

 0x0000000000000015 (DEBUG)             0x0

 0x0000000000000003 (PLTGOT)            0x600aa8

 0x0000000000000002 (PLTRELSZ)          96 (bytes)

 0x0000000000000014 (PLTREL)            RELA

 0x0000000000000017 (JMPREL)            0x4004c0

 0x0000000000000007 (RELA)              0x400490

 0x0000000000000008 (RELASZ)            48 (bytes)

 0x0000000000000009 (RELAENT)           24 (bytes)

 0x000000006ffffffe (VERNEED)           0x400470

 0x000000006fffffff (VERNEEDNUM)        1

 0x000000006ffffff0 (VERSYM)            0x400454

 0x0000000000000000 (NULL)              0x0

[[email protected] pcap]$

3相關内容

3相關内容

3.1LD_LIBRARY_PATH

把動态連結庫的安裝路徑(如/usr/local/lib)放到變量LD_LIBRARY_PATH裡。

用指令export:

export LD_LIBRARY_PATH=/usr/local/lib      

這隻是臨時設定變量LD_LIBRARY_PATH,下次開機,設定将不複存在;可以在~/.bashrc或者~/.bash_profile中加入export語句,

前者在每次登陸和每次打開shell都讀取一次,

後者隻在登陸時讀取一次。

可采用如下語句來使設定生效:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib      

修改完後,記得關掉目前終端并重新打開一個新的終端,進而使上面的配置生效。

3.2 ld.so.conf

連結器ld預設的目錄是/lib和/usr/lib,如果放在其他路徑也可以,需要讓ld知道庫檔案在哪裡。

1>編輯/etc/ld.so.conf檔案,在新的一行中加入庫檔案所在目錄;

運作ldconfig,以更新/etc/ld.so.cache檔案;

2>在/etc/ld.so.conf.d/目錄下建立任何以.conf為字尾的檔案,在該檔案中加入庫檔案所在的目錄;

運作ldconfig,以更新/etc/ld.so.cache檔案;

第二種辦法更為友善,對于原系統的改動最小。因為/etc/ld.so.conf檔案的内容是include/etc/ld.so.conf.d/*.conf,是以,在/etc/ld.so.conf.d/目錄下加入的任何以.conf為字尾的檔案都能被識别到。

[[email protected]]$ ls /etc/ld.so.conf.d/

gmp.conf  mpc.conf mpfr.conf  qt-x86_64.conf

[[email protected] pcap]$ ls/etc/ld.so.conf.d/

gmp.conf  mpc.conf  mpfr.conf pcap.conf  qt-x86_64.conf

[[email protected] pcap]$ cat/etc/ld.so.conf.d/pcap.conf

/usr/local/lib/

[[email protected]]$

ld.so.cache的更新是遞增式的,就像PATH系統環境變量一樣,不是從頭重建立立,而是向上累加。

除非重新開機,才是從零開始建立ld.so.cache檔案。

3.3指令

NAME

      /sbin/ldconfig - configure dynamic linker runtime bindings

SYNOPSIS

      /sbin/ldconfig [ -nNvXV ] [ -f conf ] [ -C cache ] [ -r root ]directory ...

       /sbin/ldconfig-l [ -v ] library ...

      /sbin/ldconfig -p

DESCRIPTION

      ldconfig  creates  the  necessary links and cache tothe most recent shared libraries found inthedirectories

       specified on thecommand line, in  the  file  /etc/ld.so.conf, and  in  the  trusted  directories  (/lib and

       /usr/lib).  The  cache  is used by the run-time linker, ld.so orld-linux.so.  ldconfig checks the header and

      filenames of the libraries it encounters when determining whichversions should have their links updated.

       ldconfigwill attempt to deduce the type of ELF libs (ie. libc5 orlibc6/glibc) based on what C libs, if  any,

      the  library  was  linked  against.  Therefore,  when making dynamic libraries, it is wise toexplicitly link

       against libc(use -lc).

       Someexisting libs do not contain enough information to allow thededuction  of  their  type.  Therefore, the

       /etc/ld.so.conf file  format  allows  the specification of an expectedtype.  This is only used for those ELF

      libs which we can not work out. The format is "dirname=TYPE",where TYPE can be libc4, libc5, or libc6.  (This

      syntax  also  works  on  the command line.) Spaces are not allowed.  Also see the -p option.  ldconfigshould

       normally be run by thesuperuser as it may require write permission on some root owneddirectories and  files.

OPTIONS

      -v     Verbose mode.  Print current versionnumber, the name of each directory as it is scanned, and anylinks

             that are created.  Overrides quiet mode.

       -n    Only process directories specified on the command line.  Don’tprocess the  trusted  directories  (/lib

             and /usr/lib) nor those specified in /etc/ld.so.conf.  Implies-N.

       -N    Don’t rebuild the cache.  Unless -X is also specified, linksare still updated.

       -X    Don’t update links.  Unless -N is also specified, the cache isstill rebuilt.

       -fconf

             Use conf instead of /etc/ld.so.conf.

       -Ccache

             Use cache instead of /etc/ld.so.cache.

       -rroot

             Change to and use root as the root directory.

       -l    Library mode. Manually link individual libraries. Intended for use byexperts only.

       -p    Print the lists of directories and candidate libraries stored in thecurrent cache.

FILES

      /lib/ld.so         run-time linker/loader

      /etc/ld.so.conf     File  containing a  list of colon, space, tab, newline, or comma-separateddirectories in

                          which to search for libraries.

      /etc/ld.so.cache    File containing an ordered list of  libraries  found  in  the  directories specified  in

                          /etc/ld.so.conf.

NAME

      ldd - print shared library dependencies

SYNOPSIS

      ldd [OPTION]...  FILE...

DESCRIPTION

      ldd prints the shared libraries required byeach program or shared library specified on the command line.

OPTIONS

      --version

             Print the version number of ldd.

       -v--verbose

             Print all information, including e.g. symbol versioning information.

       -u--unused

             Print unused direct dependencies.

       -d--data-relocs

             Perform relocations and report any missing objects (ELFonly).

       -r--function-relocs

             Perform  relocations  for  both data objects andfunctions, and report any missing objects or functions

             (ELF only).

       --helpUsage information.

NOTES

      The standard version of ldd comes with glibc2. Libc5 came with anolder version, still present  on  some  sys-

      tems. The long options are not supported by the libc5 version. On the other hand, the glibc2 version does not

      support -V and only has the equivalent --version.

       Thelibc5 version of this program will use the name of a library given onthe command line as-is when it  con-

      tains a ’/’; otherwise it searches for the library in thestandard locations. To run it on a shared library in

      the current directory, prefix the name with "./".

BUGS

      ldd does not work on a.out shared libraries.

       ldddoes not work with some extremely old a.out programs which were builtbefore ldd support was added to  the

      compiler releases.  If you use ldd on one of these programs, theprogram will attempt to run with argc = 0 and

      the results will be unpredictable.

SEE ALSO

      ld.so(8), ldconfig(8)

NAME

      ld.so, ld-linux.so* - dynamic linker/loader

DESCRIPTION

      The  programs ld.so and ld-linux.so* find and load the sharedlibraries

       needed by aprogram, prepare the program to run, and then run it.

       Linuxbinaries require dynamic linking (linking at run time) unlessthe

       -static option was givento ld during compilation.

       The program  ld.so handles a.out binaries, a format used long ago;ld-

       linux.so* handles ELF(/lib/ld-linux.so.1 for libc5, /lib/ld-linux.so.2

      for  glibc2),  which everybody has been using for yearsnow.  Otherwise

       bothhave the same behaviour, and use the same support files  and pro-

       grams ldd(1),ldconfig(8) and /etc/ld.so.conf.

       The shared libraries needed by the program are searched for invarious

       places:

       o     (ELF only) Using the DT_RPATH dynamic section attribute  of the

             binary  if present and DT_RUNPATH attribute does not exist. Use

             of DT_RPATH is deprecated.

       o     Using the environment variable LD_LIBRARY_PATH.  Except if  the

             executable  is  a set-user-ID/set-group-ID binary, in whichcase

             it is ignored.

       o     (ELF only) Using the DT_RUNPATH dynamic section attribute ofthe

             binary if present.

       o     From  the  cache file /etc/ld.so.cache which contains acompiled

             list of candidate libraries previously found  in  the augmented

             library  path.  If, however, the binary was linked with -znode-

             flib linker option, libraries in the default library  paths are

             skipped.

       o     In  the default path /lib, and then /usr/lib.  If thebinary was

             linked with -z nodeflib linker option, this step is skipped.

SYNOPSIS

      The dynamic linker can be run either indirectly  through running  some

      dynamically  linked  program  or library (in whichcase no command line

       optionsto the dynamic linker can be passed and, in the ELF  case, the

       dynamic linker which isstored in the .interp section of the program is

      executed) or directly by running:

       /lib/ld-linux.so.* [OPTIONS] [PROGRAM [ARGUMENTS]]

COMMAND LINEOPTIONS

       --list List alldependencies and how they are resolved.

       --verify

             Verify that program  is  dynamically  linked and  this  dynamic

             linker can handle it.

       --library-pathPATH

             Override   LD_LIBRARY_PATH  environment variable  setting  (see

             below).

       --ignore-rpathLIST

             Ignore RPATH and RUNPATH information in object  names  in LIST.

             This  option  has  been  supported by glibc2 forabout one hour.

             Then it was renamed into:

       --inhibit-rpathLIST

ENVIRONMENT

      There are four important environment variables.

       LD_LIBRARY_PATH

             A colon-separated list of directories in which to search forELF

             libraries  at  execution-time.   Similar to thePATH environment

             variable.

       LD_PRELOAD

             A whitespace-separated list of additional,  user-specified, ELF

             shared  libraries  to  be loaded before all others. This can be

             used  to  selectively  override  functions  in   other   shared

             libraries.   For  set-user-ID/set-group-ID  ELF binaries,  only

             libraries in the standard search directories that are also set-

             user-ID will be loaded.

       LD_BIND_NOW

             (libc5;  glibc  since  2.1.1) If set to non-emptystring, causes

             the dynamic linker to resolve all  symbols  at program  startup

             instead  of  deferring  function call resolval to thepoint when

             they are first referenced.  This is useful when using  a debug-

             ger.

      LD_TRACE_LOADED_OBJECTS

             (ELF  only)  If  set  to non-empty string, causesthe program to

             list its dynamic library dependencies,  as  if  run by  ldd(1),

             instead of running normally.

       Thenthere are lots of more or less obscure variables, many obsoleteor

       only for internal use.

       LD_WARN

             (ELF only)(glibc since 2.1.3) If set to non-empty  string, warn

             about unresolved symbols.

       LD_NOWARN

             (a.out only)(libc5) Suppress warnings about a.out librarieswith

             incompatible minor version numbers.

       LD_BIND_NOT

             (glibc since 2.1.95) Do not update the GOT (global offsettable)

             and PLT (procedure linkage table) after resolving a symbol.

       LD_DEBUG

             (glibc since 2.1) Output verbose debugging information aboutthe

             dynamic linker.  If set to all prints all debugging information

             it  has,  if set to help prints a help message about whichcate-

             gories can be specified in this environment variable.

       LD_DEBUG_OUTPUT

             (glibc since 2.1) File where LD_DEBUG output should be fedinto,

             default is standard output.  LD_DEBUG_OUTPUT is ignored forset-

             user-ID/set-group-ID binaries.

       LD_VERBOSE

             (glibc since 2.1) If set to non-empty string, output symbolver-

             sioning  information  about  the program if queryinginformation

             about the program (ie. either LD_TRACE_LOADED_OBJECTS  has been

             set,  or  --list  or  --verify  options have  been given to the

             dynamic linker).

       LD_PROFILE

             (glibc since 2.1) Shared object to be profiled.

      LD_PROFILE_OUTPUT

             (glibc since 2.1) File where LD_PROFILE output should bestored,

             default  is  standard  output.  LD_PROFILE_OUTPUTis ignored for

             set-user-ID/set-group-ID binaries.

      LD_AOUT_LIBRARY_PATH

             (libc5) Version of LD_LIBRARY_PATH for a.out binaries only. Old

             versions of ld-linux.so.1 also supported LD_ELF_LIBRARY_PATH.

       LD_AOUT_PRELOAD

             (libc5) Version of LD_PRELOAD for a.out binaries only.  Oldver-

             sions of ld-linux.so.1 also supported LD_ELF_PRELOAD.

       LD_SHOW_AUXV

             (glibc since 2.1) Show auxiliary array passed up from  the ker-

             nel.

       LD_HWCAP_MASK

             (glibc since 2.1) Mask for hardware capabilities.

       LD_ORIGIN_PATH

             (glibc  since  2.1) Path where the binary is found (fornon-set-

             user-ID programs).

       LD_DYNAMIC_WEAK

             (glibc  since  2.1.91)  Allow  weak symbols  to  be  overridden

             (reverting to old glibc behaviour).

       LD_KEEPDIR

             (a.out  only)(libc5)  Don’t ignore the directory in thenames of

             a.out libraries to be loaded.  Use of this  option is  strongly

             discouraged.

       LDD_ARGV0

             (libc5) argv[0] to be used by ldd(1) when none is present.

FILES

      /lib/ld.so

             a.out dynamic linker/loader

      /lib/ld-linux.so.{1,2}

             ELF dynamic linker/loader

      /etc/ld.so.cache

             File  containing  a  compiled  list  of directories in which to

             search for libraries and an ordered list of candidatelibraries.

      /etc/ld.so.preload

             File  containing  a  whitespace  separated list  of  ELF shared

             libraries to be loaded before the program.

      lib*.so*

             shared libraries

NOTES

      The ld.so functionality is available  for  executables compiled  using

       libc version  4.4.3  or greater.  ELF functionality isavailable since

       Linux 1.1.52and libc5.

SEE ALSO

      ldd(1), ldconfig(8)