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共享库不必慌张,原理就是如此。希望对大家有所帮助!

相关推荐
Yolanda_20222 小时前
15.dataloader的使用
python
BullSmall2 小时前
规则+大模型混合评测:高效精准双保障
运维·自动化
网硕互联的小客服8 小时前
Linux服务器磁盘应该如何合理分区?
linux·运维·服务器
楚识科技8 小时前
合同比对全流程自动化:OCR识别+差异比对+法律风险字段抽取实战指南
运维·自动化·ocr
杨杨杨大侠8 小时前
Jev、Kev、Laya:决策模型怎么选,什么时候需要微调?
人工智能·python·agent
代码方舟8 小时前
零信任架构实战:基于天远人企关联构建自动化供应链金融网关
运维·人工智能·架构·自动化
LOVE️YOU9 小时前
Python 在定义函数时,究竟定义的是什么?
python
段一凡-华北理工大学9 小时前
大模型应用开发 100 天:Python + LLM 从入门到精通 day26~Prompt 调试与优化——A/B 测试与效果评估
windows·python·大模型·prompt·智能体·提示词工程·高炉智能化
Minecraft红客9 小时前
以撒的结合
python·游戏·电脑·娱乐
Circ.9 小时前
Python 调试 Litellm 本地大模型接口:模型列表与对话接口实操踩坑记录
开发语言·python