【问题标题】:In what order does ld-linux.so search shared libraries?ld-linux.so 以什么顺序搜索共享库?
【发布时间】:2010-09-01 09:02:35
【问题描述】:

当 ld-linux 解析一个符号时,它会按特定顺序搜索共享库,并在找到具有匹配符号的共享库时停止。

什么决定了它在库中搜索的顺序?如果未解析的符号在主程序中还是在另一个共享库中,是否会有所不同?

如何在不调用 ldd 等外部​​程序的情况下以编程方式确定搜索顺序?

【问题讨论】:

    标签: linux linker shared-libraries


    【解决方案1】:

    来自http://www.muppetlabs.com/~breadbox/software/ELF.txt(如 sarnold 所述):

    解析符号引用时, 动态链接器检查符号 具有广度优先搜索的表。 也就是先看符号 可执行程序表 本身,然后在符号表中 DT_NEEDED 条目(按顺序),然​​后 在第二级 DT_NEEDED 条目, 等等。

    【讨论】:

      【解决方案2】:

      本书http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html 建议使用gcc 命令行中给出的从左到右的顺序。 (我很久以前就学会了始终将 -lm 作为要链接的库列表中的最后一个库,但我也早已忘记了货物崇拜的原因。)

      编辑

      啊哈,感谢您的更新。您将需要自己解析 ELF;在http://www.muppetlabs.com/~breadbox/software/ELF.txt 中查找“共享对象依赖项”和“DT_RPATH”。 (我也推荐http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html,但它不太适用于你的问题——只是有趣的阅读。)

      /usr/include/linux/elf.h 具有所有类型定义。

      【讨论】:

      • 谢谢,但我需要它来处理任意程序,即使我不知道编译程序的链接行。
      【解决方案3】:

      其实链接顺序可以用ldd推导出来; 如果 library1 在 library2 之前的链接器命令行中,则 ldd 将在 library2 之前显示 library1

      现在基于此,我编写了一个简短的 python 脚本,以链接顺序显示共享库 - 它对 ldd 显示的所有依赖项进行广度优先搜索(对于给定的可执行文件。

      这是脚本

      编辑:请注意脚本使用 ldd,仍然可能有用 ;-)

      #!/usr/bin/python
      
      import subprocess
      import sys
      import re
      
      visited_so = {}
      ssplit = re.compile('\S+')
      verbose = 0
      
      def run_ldd( sopath ):
              ret = []
      
              pop = subprocess.Popen( [ 'ldd', sopath ], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
              [out, err] = pop.communicate()
      
              for l in out.splitlines():
                  toks = ssplit.findall( l )
                  if len(toks) > 3:
                      ret.append( toks[2] )
              return ret
      
      def load_order_bfs( pqueue ):
          while len(pqueue) != 0:
              nextexe = pqueue.pop(0)
              if verbose:
                  print 'visit ' + nextexe
      
              if not nextexe in visited_so:
                  print nextexe
                  visited_so[ nextexe ] = 1
      
                  dependents = run_ldd( nextexe )
                  for sopath in dependents:
                          if not sopath in visited_so:
                              if verbose:
                                  print '\tnext ' + sopath
                              pqueue.append( sopath )
      
      if len( sys.argv ) == 1:
          print sys.argv[0] + """ <path>
      shows dependents of executable in symbol search order;
      does a breadth first search over the dependents of the executable
      """
          sys.exit(1)
      
      load_order_bfs( [ sys.argv[1] ] )       
      

      【讨论】:

      • 问题是“不调用像ldd这样的外部程序”。你的程序调用了一个外部程序,即 ldd。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 2019-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多