Linux动态库常见问题之-"cannot open shared object file No such file or directory"的解决办法

简介: Linux编写程序时,会经常的接触动态库,而在程序运行时可能会遇到类似于:libxxx.so cannot open shared object file No such file or directory的问题,这个代表什么含义,该怎么解决呢?

含义


这个问题代表的含义是,可执行程序在加载libxxx.so库时,找不到该库。至于找不到的情况分为两种:系统里根本不存在libxxx.so库;libxxx.so库在系统中存在,但是ld找不到,即libxxx.so库的位置没有告知ld。


解决办法


对于第一种情况,需要将libxxx.so放到系统ld的搜索路径中;对于第二种情况,通过locate工具定位libxxx.so的位置,然后将其放到ld的搜索路径中。


动态库的搜索路径配置


Linux下ld对于动态库的搜索路径的配置方式包括以下几种方式:


  1. 通过配置gcc编译器的参数-Wl,-rpath指定;


  1. 通过LD_LIBRARY_PATH环境变量指定;


  1. 通过/etc/ld.so.conf指定,切记修改完ld.so.conf之后必须执行/sbin/ldconfig -v同步动态库;


  1. 默认搜素路径/lib、/usr/lib/指定;


同时,上述几种方式存在一定的搜索顺序,按照搜索的先后依次为:1 > 2 > 3 > 4。对于动态库的搜索路径的配置可以参考21aspnet的这篇博文


依赖动态库的查看


我们可以通过ldd(x86环境)或者CROSS_COMPILE-readelf -d(ARM环境,CROSS_COMPILE为具体交叉编译前缀,-d 为读取动态库信息的参数)来分析相应平台下可执行程序所依赖的动态库的情况,我们可以举一例:


test.c:
#include <stdio.h>                                                                                                                                                                                                  
void test() 
{
    printf("test()\n");
}
$ $(CC) -fPIC -c test.c //生成test.o,-fPIC(Position-independent code)为了生成位置无关的代码,一般用于动态库编译选项。
$ $(CC) -static -fPIC -o libtest.so test.o
extern void test();                                                                                                                                                                                                 
main.c:
int main()
{
    test();
    return 0;
}
$ $(CC) -c main.c
$ $(CC) main.o -o main -L. -ltest
其中,CC代表不同平台的编译器;


通过,修改CC为gcc或者arm-linux-gnueabi-gcc分别生成X86、ARM平台下的main可执行程序,下面分别通过ldd和arm-linux-gnueabi-readelf查看main所依赖的动态库:


  • X86:


ldd main
  linux-vdso.so.1 =>  (0x00007ffc98f6a000)
  libtest.so => /home/qihua/develop/linux/static_dynamic_libs/code/libtest.so (0x00007fe850df4000)
  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe850a10000)
  /lib64/ld-linux-x86-64.so.2 (0x000055950a132000)


  • ARM:


arm-linux-gnueabi-readelf -d  main
  Dynamic section at offset 0xf10 contains 25 entries:
    标记        类型                         名称/值
   0x00000001 (NEEDED)                     共享库:[libtest.so]
   0x00000001 (NEEDED)                     共享库:[libc.so.6]
   0x0000000c (INIT)                       0x10430
   0x0000000d (FINI)                       0x10590
   0x00000019 (INIT_ARRAY)                 0x20f08
   0x0000001b (INIT_ARRAYSZ)               4 (bytes)
   0x0000001a (FINI_ARRAY)                 0x20f0c
   0x0000001c (FINI_ARRAYSZ)               4 (bytes)
   0x00000004 (HASH)                       0x101ac
   0x00000005 (STRTAB)                     0x10300
   0x00000006 (SYMTAB)                     0x10200
   0x0000000a (STRSZ)                      200 (bytes)
   0x0000000b (SYMENT)                     16 (bytes)
   0x00000015 (DEBUG)                      0x0
   0x00000003 (PLTGOT)                     0x21000
   0x00000002 (PLTRELSZ)                   32 (bytes)
   0x00000014 (PLTREL)                     REL
   0x00000017 (JMPREL)                     0x10410
   0x00000011 (REL)                        0x10408
   0x00000012 (RELSZ)                      8 (bytes)
   0x00000013 (RELENT)                     8 (bytes)
   0x6ffffffe (VERNEED)                    0x103e8
   0x6fffffff (VERNEEDNUM)                 1
   0x6ffffff0 (VERSYM)                     0x103c8
   0x00000000 (NULL)                       0x0


NOTE


  1. 如果一个可执行程序(常见于第三方库提供的bin)依赖了某些动态库,但可执行程序的CPU架构与本地的CPU架构不同(例如,可执行程序为32位,但本地系统为64位,本地系统安装的动态库也为64位的),那么程序运行时,通过会提示:libxxx.so cannot open shared object file No such file or directory。这是,我们通过locate是可以定位到libxxx.so库,并且libxxx.so处于合适的ld搜索路径之下,这是我们通过修改libxxx.so路径是没有用的。解决问题的方式有这么几种:


1)下载与本地系统CPU架构相匹配的程序;


2)在本地系统重新编译该程序;


3)编译、更新与可执行程序CPU架构相匹配的动态库;


相关文章
|
5月前
|
安全 Linux vr&ar
Linux的动态库和静态库
Linux的动态库和静态库
|
4月前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
4月前
|
Docker 容器
14 response from daemon: open \\.\pipe\docker_engine_linux: The system cannot find the file speci
14 response from daemon: open \\.\pipe\docker_engine_linux: The system cannot find the file speci
49 1
|
5月前
|
应用服务中间件 Shell 网络安全
nginx安装提示 libssl.so.3: cannot open shared object file: No
【8月更文挑战第1天】### 原因 未将安装的ssl中的`libssl.so.3`链接到`/usr/lib`导致缺失。 ### 解决方案 1. 检查openssl是否已安装,若为低版本则需重装。 ```sh whereis openssl
2538 6
|
5月前
|
Ubuntu
Ubuntu22.04,AOSP编译报错: libncurses.so.5: cannot open shared object file: No such file
本文描述了在Ubuntu 22.04系统上编译AOSP时遇到的`libncurses.so.5`缺失错误,并提供了通过安装相应库解决该问题的步骤。
690 0
|
5月前
|
Kubernetes Linux Docker
【Azure 应用服务】使用Docker Compose创建App Service遇见"Linux Version is too long. It cannot be more than 4000 characters"错误
【Azure 应用服务】使用Docker Compose创建App Service遇见"Linux Version is too long. It cannot be more than 4000 characters"错误
|
6月前
|
关系型数据库 MySQL
mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file
mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file
559 2
|
2月前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
172 8
|
2月前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
710 6
|
2月前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
120 3