【问题标题】:How to see the order of shared library loading如何查看共享库加载的顺序
【发布时间】:2017-03-30 22:57:33
【问题描述】:

给定一个 ELF 二进制文件或共享对象,我怎样才能最容易地查看所需共享库的加载顺序?

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

【问题讨论】:

    标签: linker shared-libraries elf


    【解决方案1】:

    如何才能最轻松地查看所需共享库的加载顺序?

    使用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)。

    【讨论】:

      【解决方案2】:

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

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

      取决于您所说的“已加载”。初始化程序返回后,库就“完全加载”了。

      在该定义下,否:readelf -d 中列出的NEEDED 依赖项的顺序和加载顺序不一样。

      考虑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

      【讨论】:

      • 感谢您的详细解答。特别是,知道初始化顺序不一定与库加载顺序相同,这对我很有用(将来可能对其他人也有用)。
      • 对于上下文,我问这个的原因是我们的库初始化器有一个排序条件,但它们没有设置优先级。在想出解决办法之前,我想确保我理解了问题所在。
      猜你喜欢
      • 2012-09-19
      • 2012-05-02
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 2012-11-18
      • 2019-04-17
      • 1970-01-01
      • 2021-05-23
      相关资源
      最近更新 更多