在Ubuntu系统中查看依赖库信息

zxl19 2023-03-21

记录一下如何在Ubuntu系统中查看依赖库信息。

使用ldconfig命令

命令说明

  1. ldconfig命令用于为共享库(shared library)依赖项配置符号链接(symbolic link)和缓存;
  2. 默认搜索/lib/usr/lib目录以及/etc/ld.so.conf配置文件中的目录;
  3. 语法说明:

     ldconfig [-nNvXV] [-f conf] [-C cache] [-r root] directory...
     ldconfig -l [-v] library...
     ldconfig -p
    

常用语法

  1. 更新符号链接并重新构建缓存(通常在新安装库时进行):

     sudo ldconfig
    
  2. 更新指定目录的符号链接:

     sudo ldconfig -n path/to/directory
    
  3. 打印缓存中的库并检查指定的库是否存在:

     ldconfig -p | grep library_name
     ldconfig --print-cache | grep library_name
    

    常用于检查系统中是否安装指定的共享库。

使用ldd命令

命令说明

  1. ldd命令用于显示二进制文件的共享库依赖项;
  2. 对于不受信任的二进制文件不能使用ldd命令,需要使用objdump命令,将在后文中详述;
  3. 对于不同系统架构的二进制文件不能使用ldd命令,需要使用readelf命令,将在后文中详述;
  4. 语法说明:

     ldd [option]... file...
    

常用语法

  1. 显示二进制文件的共享库依赖项:

     ldd path/to/binary
    
  2. 显示关于依赖项的所有信息:

     ldd -v path/to/binary
     ldd --verbose path/to/binary
    
  3. 显示未使用的直接依赖项:

     ldd -u path/to/binary
     ldd --unused path/to/binary
    
  4. 报告丢失的数据对象并进行数据重定位:

     ldd -d path/to/binary
     ldd --data-relocs path/to/binary
    
  5. 报告丢失的数据对象和函数,并对于两者进行重定位:

     ldd -r path/to/binary
     ldd --function-relocs path/to/binary
    

    常用于检查链接共享库时存在的未定义符号问题,可能有四种原因:

    • 未将依赖的共享库添加到CMakeLists.txt中或者依赖的共享库不存在;
    • 在生成依赖的共享库时未将.cpp文件添加到CMakeLists.txt中;
    • 静态数据成员未在类外初始化;
    • 在与C语言混合编程时没有添加extern "C";

使用objdump命令

命令说明

  1. objdump命令用于查看关于对象文件的信息;
  2. 语法说明:

     objdump <option(s)> <file(s)>
    

常用语法

  1. 显示文件头(file header)信息:

     objdump -f binary
     objdump --file-headers binary
    
  2. 显示可执行部分的反汇编(disassembled)输出:

     objdump -d binary
     objdump --disassemble binary
    
  3. 以Intel语法显示可执行部分的反汇编输出:

     objdump -M intel -d binary
     objdump --disassembler-options=intel --disassemble binary
    
  4. 显示完整二进制文件所有部分的十六进制转储(hex dump):

     objdump -s binary
     objdump --full-contents binary
    
  5. 显示所有报头(header)的内容并查看共享库依赖项:

     objdump -x binary | grep NEEDED
     objdump --all-headers binary | grep NEEDED
    

    常用于查看共享库依赖项的名称。

使用readelf命令

命令说明

  1. readelf命令用于显示ELF文件信息;
  2. 语法说明:

     readelf <option(s)> <file(s)>
    

常用语法

  1. 显示有关ELF文件的所有信息:

     readelf -a path/to/binary
     readelf --all path/to/binary
    
  2. 显示ELF文件中存在的所有报头:

     readelf -e path/to/binary
     readelf --headers path/to/binary
    
  3. 显示ELF文件的符号表部分中的条目:

     readelf -s path/to/binary
     readelf --syms path/to/binary
     readelf --symbols path/to/binary
    
  4. 显示ELF文件的文件头中包含的信息:

     readelf -h path/to/binary
     readelf --file-header path/to/binary
    
  5. 显示ELF文件的动态部分并查看共享库依赖项:

     readelf -d path/to/binary | grep NEEDED
     readelf --dynamic path/to/binary | grep NEEDED
    

    常用于查看不同系统架构下的共享库依赖项名称。

使用c++filt命令

命令说明

  1. c++filt命令用于还原(demangle)C++和Java符号;
  2. 语法说明:

     c++filt [options] [mangled names]
    
  3. 常用于解析编译后的符号名,从而恢复编译前的函数名;

使用nm命令

命令说明

  1. nm命令用于列出对象文件中的符号名称;
  2. 语法说明:

     nm [option(s)] [file(s)]
    
  3. 默认对象文件名为a.out

常用语法

  1. 列出文件中的全局函数和外部函数,前缀为T

     nm -g path/to/file.o
     nm --extern-only path/to/file.o
    
  2. 列出文件中的未定义符号:

     nm -u path/to/file.o
     nm --undefined-only path/to/file.o
    
  3. 列出文件中的全部符号,包括调试符号:

     nm -a path/to/file.o
     nm --debug-syms path/to/file.o
    
  4. 还原C++符号,使其可读:

     nm -C path/to/file.o
     nm --demangle path/to/file.o
    
  5. 在每个符号前打印输入文件的名称并查看指定符号:

     nm -A path/to/file.o | grep symbol_name
     nm --print-file-name path/to/file.o | grep symbol_name
    

    常用于查看指定的符号是否被定义,未定义符号前缀为U

使用chrpath命令

命令说明

  1. chrpath命令用于查看和修改二进制文件的运行时路径(runtime path,rpath)和运行时搜索路径(run-time search path,runpath)信息;
  2. 语法说明:

     chrpath [-v|-d|-c|-r <path>] <program> [<program> ...]
    
  3. 可用于修改可执行文件的rpath信息,使其在依赖库发生变化的环境中运行,一般情况下不建议使用;

使用patchelf命令

命令说明

  1. patchelf命令用于修改ELF文件信息;
  2. 语法说明:

     patchelf [--set-interpreter FILENAME] [--page-size SIZE]
              [--print-interpreter] [--print-soname]
              [--set-soname SONAME] [--set-rpath RPATH] [--remove-rpath]
              [--shrink-rpath] [--print-rpath] [--force-rpath]
              [--add-needed LIBRARY] [--remove-needed LIBRARY] [--replace-needed LIBRARY NEW_LIBRARY]
              [--print-needed] [--no-default-lib] [--debug] [--version]
              FILENAME
    
  3. 可用于修改可执行文件的rpath信息,使其在依赖库发生变化的环境中运行,一般情况下不建议使用;

参考

  1. undefined symbol问题的查找、定位与解决方法-CSDN博客
  2. Linux动态库undefined symbol原因定位与解决方法-CSDN博客
  3. Linux动态库undefined symbol原因定位与解决方法-博客园
  4. 未定义符号的链接问题通用解决方法-博客园
  5. c++符号表解析-CSDN博客
  6. ldconfig命令-五月的麦田
  7. C/C++开发技巧:ldconfig,ldd,objdump,readelf,lsof动态库命令行工具-CSDN博客
  8. linux下nm,objdump和ldd三大工具使用-CSDN博客
  9. C++的“坑”之一:undefined reference-CrackingOysters的文章-知乎
  10. mangle和demangle-博客园
  11. 一文搞懂动态链接库的各种路径的意义与设置-卷儿的文章-知乎
  12. NixOS/patchelf