【发布时间】:2017-03-30 22:57:33
【问题描述】:
给定一个 ELF 二进制文件或共享对象,我怎样才能最容易地查看所需共享库的加载顺序?
它们是否按照readelf -d 列出的顺序加载?
【问题讨论】:
标签: linker shared-libraries elf
给定一个 ELF 二进制文件或共享对象,我怎样才能最容易地查看所需共享库的加载顺序?
它们是否按照readelf -d 列出的顺序加载?
【问题讨论】:
标签: linker shared-libraries elf
如何才能最轻松地查看所需共享库的加载顺序?
使用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)。
【讨论】:
使用LD_DEBUG=files 允许您查看库的搜索顺序,和它们的初始化顺序。后者可能与前者不同。
它们是否按照
readelf -d列出的顺序加载
取决于您所说的“已加载”。初始化程序返回后,库就“完全加载”了。
在该定义下,否:readelf -d 中列出的NEEDED 依赖项的顺序和加载顺序不一样。
考虑a.out,它依赖于libA.so 和libB.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.so 和libD.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
其他可能影响加载顺序的因素:
LD_PRELOAD 或 /etc/ld.so.preload。dlopen。【讨论】: