【问题标题】:How do I find where a symbol is defined among static libraries如何找到在静态库中定义符号的位置
【发布时间】:2013-11-23 19:56:55
【问题描述】:

假设您使用由多个工具和库组成的代码库,并且您希望在此类代码库中移植(或恢复)某些组件,但是有关符号在各个库中的位置的任何线索要么丢失,要么需要很长时间才能找到查看代码本身(是的,改进的文档可以避免此类问题,但要求很高)。发现在哪个库中可以找到代码中使用的符号的最快方法是什么?

【问题讨论】:

    标签: c++ linker libraries undefined-symbol


    【解决方案1】:

    假设一个 linux 机器,nm 工具会在库文件中列出名称。

    它可以用来做一个广泛的搜索,如下:可以先用一个find找到所有可用的库(假设项目已经成功编译,没有你要添加的组件),然后这个find可以包含在一个在所有发现的库上调用 nm 的循环;然后 grep 的输出以丢弃“U”引用(未定义的符号,也就是在其他地方使用该符号)。在一个 bash 行上给出:

    for lib in $(find base_path -name \*.a) ; do echo $lib ; nm $lib | grep my_symbol | grep -v " U "   ; done
    

    地点:

    • base_path 是代码库的根
    • my_symbol 是您要查找的符号

    echo 生成所有找到的库的列表,它不是很干净,因为它输出不包含符号的库的名称,但它是我发现直接引用库的最快方法,所以当你看到:

    base_path/component/libA.a
    0000000000000080 D my_symbol
    

    你找到了你通常的嫌疑人。

    【讨论】:

    • nm 的 -A 选项将打印文件名。消除了在您的示例中回显 $lib 的需要。
    【解决方案2】:

    使用nm,可以列出二进制中定义的符号,--defined-only 开关忽略未定义的引用。

    选项 1:find

    在单个命令中:

    find $path -name \*.a -exec bash -c "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}" \;
    

    其中$path 是包含二进制文件的文件树的根,$symbol 是您要查找的符号的名称。

    选项 2:find + GNU parallel

    在所有文件上运行 nm 可能需要一些时间,因此并行处理 find 的结果可能会有所帮助(使用 GNU parallel):

    find $path -name \*.a | parallel "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}"
    

    选项 3:fd

    最后,我的最爱。使用fd 工具,它的语法比find 更简单,通常速度更快,并且默认并行处理结果:

    fd '.*\.a$' -x bash -c "nm --defined-only {} 2>/dev/null | grep $symbol && echo {}"
    

    简单基准

    在我的笔记本电脑上搜索/usr/lib 中的gz_write 符号:

    • find 大约需要 23 秒
    • find | parallel 大约需要 10 秒
    • fd 大约需要 8 秒

    【讨论】:

      【解决方案3】:

      在这里使用 nm 的 --defined-only 开关很有帮助,因为它会删除未定义的引用。下面是一个可能对其他人有用的 csh 脚本。

      #!/bin/csh
      #
      #recurse from current dir and output name of any .a files
      #that contain the desired symbol.
      echo "Search for: $1"
      foreach i (`find . -name '*.a'`)
          nm --defined-only $i | grep $1
          if ($status == 0) then
              echo $i
          endif
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-17
        • 1970-01-01
        • 1970-01-01
        • 2016-02-24
        • 1970-01-01
        相关资源
        最近更新 更多