Linux动态链接库

一、背景

我们使用Linux的过程中,例如安装程序或者部署一些如Python等,可能会遇到过如下动态链接库(共享库)报错:

ImportError: libcrypto.so.10: cannot open shared object file: No such file or directory

bash 复制代码
$"./lib/python3.8/lib/python3.8/ssl.py", line 98, in <module> import _ssl 
# if we can't import it, let the error propagate ImportError: 
libcrypto.so.10: cannot open shared object file: No such file or directory

例如这里的是报错,libcrypto.so.10 动态库没找到.

那我们来分析一下,Linux动态链接库的一个查找过程是怎么样的。为什么说没找到这个文件呢? 寻找的过程是怎么样的

二、动态链接库、共享库

1、定义

在 Linux 系统中,动态链接库(Dynamic Link Library)和共享库(Shared Library)是指同一概念的不同称谓,通常指的是 .so(shared object)文件。这类库在 Linux 和其他类 Unix 操作系统中非常常见,用于实现程序的模块化和资源的共享。

动态链接库/共享库 是一种二进制文件,其中包含了一组预先编译好的函数和数据结构,可以被多个不同的程序共享。这些库通常在程序运行时被加载,并且可以被多个进程同时使用。

在 Linux 中,动态链接库通常以 .so 扩展名命名,例如 libfoo.so。这个扩展名表明这是一个共享对象文件,它可以被动态链接器加载。

Redhat系列一般存放于: /usr/lib/、/usr/lib64/ , 同时 / 下存在lib和lib64的软链接到/usr/lib、/usb/lib64/

Linux中命名系统中共享库的规则:

如文章开头缺失的共享库的名称就是crypto

2、寻找so动态链接库的过程

1、首先查找当前环境中,环境变量LD_LIBRARY_PATH路径(多路径使用:分隔,和定义PATH环境变量路径一样),依次遍历,查找是否存在libcrypto.10.so这个文件,存在则读取,停止搜索,否则继续往下执行

2、查找/etc/ld.so.cache已经缓存好的所有so动态库的路径,查看是否存在里面。存在则加载,否则查找so文件失败,程序报错. 我看可以看看/etc/ld.so.cache是什么东西? 这个是ldconfig根据/etc/ld.so.conf配置文件配置的共享库查找路径,预先查找到所有的so,记录了这些so的绝对路径形成的一个列表二进制文件(不能直接用cat打开, 使用strings打开查看内容).例如我们使用strings查看/etc/ld.so.cache文件内容:

ld.so.cache文件缓存好了查找/etc/ld.so.conf配置好的搜索动态库路径搜索到所有so的绝对路径。

这样应用程序查找的时候就没必要再次全量扫描/etc/ld.so.conf的路径下有没有对应的so了,直接从/etc/ld.so.cache匹配一下,效率更高、查找速度更快。

3、ldconfig、LD_LIBRARY_PATH、ldd命令的用处

1、ldconfig命令,重新生成/etc/ld.so.cache缓存

1、直接执行ldconfig会重新生成/etc/ld.so.cache缓存文件,一般用于,新添加了/etc/ld.so.conf搜索so的路径,需要重新生成缓存

2、ldconfig -p 查看当前缓存so路径内容, 类似strings /etc/ld.so.cache的效果

2、LD_LIBRARY_PATH 环境变量

ldconfig适用于全局的so查找路径。 但是因为作为全局,一般兼容性高,很少存在版本冲突问题。 如果我们应对的是相同的共享库,但是是这个共享库的不同版本。 例如我的A程序依赖于ssl的v1版本,但是系统依赖的是ssl的v2版本等等。 这就蛋疼了, 那这个ssl库保留哪个版本呢? 单独保留某一个版本,都无法满足需求。 要操作系统依赖的存在问题、要么应用程序存在问题。

所以,Linux提供给我们这个LD_LIBRARY_PATH环境变量,就是解决这种多版本问题。 可以作为临时设置so查找的路径,这样可以避免版本冲突以及查找优先级.

例如设置export LD_LIBRARY_PATH=/my/v1/:$LD_LIBRARY_PATH, 先把自己A程序查找共享库的路径放到前面,其它放在后面,那么一旦从我们的v1找到,就停止搜索了,后面v2的ssl.so就不会被搜索到了.

1、提高so共享库查找的优先级

2、可以解决版本冲突问题

3、ldd命令,查看一个二进制命令依赖共享库的信息

有时候我们关于共享库报错,那么我们想看下这个二进制是缺的什么共享库,用到了哪些共享库。 可以使用 ldd $程序二进制绝对路径查看,例如查看ssh命令的共享库依赖:

从ldd结果,如果某些库找不到,那么我们需要通过yum或者其他方式安装对应这个库依赖即可解决问题

4、回到案例,排查结果

我们知道了动态库的原理,那么针对文章开头的地方,我们去看了一下确实存在问题。 libcrypto.so.10软连接指向的源文件,路径搞错了,导致找不到文件:

源文件路径多了空格,并且源文件路径不存在。 导致应用程序查找到了.so,但是无效的软链接,所以报错。

三、总结

下次遇到动态链接库报错、多版本的so共享库不必慌张,原理就是如此。希望对大家有所帮助!

相关推荐
angushine8 分钟前
qwen3-tts使用实例
python·tts
玖石书15 分钟前
Ubuntu 更换 USTC 镜像源完整指南(AMD64 / AARCH64)
linux·运维·ubuntu
zbyyd17 分钟前
Linux 进程间通信(IPC):信号、消息队列、共享内存与信号量详解
linux·运维·c语言
智脑API33 分钟前
CCSwitch Claude Code 如何配置 MCP?服务器启动、工具权限与安全测试
运维·服务器·claude·codex·ccswitch
陈年老古董1 小时前
OpenCV实战:文档扫描与图像风格迁移
人工智能·python·opencv·计算机视觉
benchmark_cc1 小时前
数据 API 稳定性为什么会影响量化策略?从数据获取到信号执行的完整分析
开发语言·python·数据分析·量化·股票数据·quantdash·量化数据源
STLearner1 小时前
KDD 2026 | (2月轮)时空数据(Spatial-Temporal)论文总结时空(交通)预测,轨迹数据挖掘(表示,生成)
论文阅读·人工智能·python·深度学习·学习·机器学习·数据挖掘
axinawang1 小时前
ddddocr--识别验证码
python
2601_962180331 小时前
python——Django 框架
开发语言·python·django
长江后浪博客1 小时前
Conda环境下测试Intel NPU:Python版本如何选择?
开发语言·python·conda·openvino·intel npu