天天看点

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)