如何查看共享库加载的顺序

时间:2016-11-16 16:29:26

标签: linker shared-libraries elf

鉴于ELF二进制或共享对象,我怎样才能最容易地看到加载所需共享库的顺序?

它们是按照readelf -d列出的顺序加载的吗?

2 个答案:

答案 0 :(得分:3)

使用LD_DEBUG=files可以查看库的搜索顺序,,它们的初始化顺序。后者可能与前者不同。

  

它们是按照readelf -d

列出的顺序加载的

取决于“装载”的含义。一旦初始化程序返回,库就会“完全加载”。

根据该定义,不:NEEDED中列出的readelf -d个依赖关系的顺序和加载顺序不一样。

考虑a.out,这取决于libA.solibB.so

readelf -d a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libA.so]
 0x0000000000000001 (NEEDED)             Shared library: [libB.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

此外,libA.so本身取决于libC.solibD.so

readelf -d libA.so | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libC.so]
 0x0000000000000001 (NEEDED)             Shared library: [libD.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

搜索库的顺序:

LD_DEBUG=files ./a.out |& grep 'needed by'
     49169: file=libA.so [0];  needed by ./a.out [0]
     49169: file=libB.so [0];  needed by ./a.out [0]
     49169: file=libc.so.6 [0];  needed by ./a.out [0]
     49169: file=libC.so [0];  needed by ./libA.so [0]
     49169: file=libD.so [0];  needed by ./libA.so [0]

库“完全加载”的顺序:

 LD_DEBUG=files ./a.out |& grep 'calling init'
     69038: calling init: /lib/x86_64-linux-gnu/libc.so.6
     69038: calling init: ./libD.so
     69038: calling init: ./libC.so
     69038: calling init: ./libB.so
     69038: calling init: ./libA.so

可能影响装货顺序的其他因素:

  1. LD_PRELOAD/etc/ld.so.preload
  2. 任何库都可以在其初始化程序中执行dlopen

答案 1 :(得分:0)

  

我怎样才能最容易地看到加载所需共享库的顺序?

使用LD_DEBUG:

LD_DEBUG=files /bin/ls
13444:
13444:     file=libc.so.6 [0];  needed by who [0]
...
13444:     file=libnss_files.so.2 [0];  needed by who [0]
...

了解更多信息man ld.so。

  

它们是按照readelf -d列出的顺序加载的吗?

不一定是它会受到预加载的影响(LD_PRELOAD/etc/ld.so.preload)。