Linux环境下,在不停止程序的情况下,更换动态链接库

发布时间:2025-08-11 15:22

避免在不安全的链接下下载驱动程序或软件 #生活技巧# #数码产品使用技巧# #网购数码产品鉴别#

设计软件架构时,为了以后升级考虑和层次间的解耦,会将一些功能封装到动态链接库中。当需要对方法升级时,只要保证动态链接库的API定义不变,就可以对局部功能进行升级。

   但是由于有些服务要求在更新时也不能停止服务,例如线上查询功能等,如果此时为了更新动态链接库而暂停服务,会影响用户的使用。下面的文章介绍了一种在Linux环境下,在不停止程序的情况下,更换动态链接库的方法。

在替换so文件时,如果在不停程序的情况下,直接用 cp new.so 的方式替换程序使用的动态库文件会导致正在运行中的程序崩溃。解决的办法是采用“rm+cp” 或“mv+cp” 来替代直接“cp” 的操作方法。linux系统的动态库有两种使用方法:运行时动态链接库,动态加载库并在程序控制之下使用。

1、为什么在不停程序的情况下,直接用 cp 命令替换程序使用的 so 文件,会使程序崩溃? 
很多同学在工作中遇到过这样一个问题,在替换 so 文件时,如果在不停程序的情况下,直接用cp new.so 的方式替换程序使用的动态库文件会导致正在运行中的程序崩溃,退出。这与 cp 命令的实现有关,cp 并不改变目标文件的 inode,cp 的目标文件会继承被覆盖文件的属性而非源文件。实际上它是这样实现的:

strace cp lib 2>&1 |grep open.lib..so

open("", O_RDONLY|O_LARGEFILE) = 3

open("lib", O_WRONLY|O_TRUNC|O_LARGEFILE) = 4

在 cp 使用“O_WRONLY|O_TRUNC” 打开目标文件时,原 so 文件的镜像被意外的破坏了。这样动态链接器 不能访问到 so 文件中的函数入口。从而导致 Segmentation fault,程序崩溃。 加载 so 文件及“再定位”的机制比较复杂,详情可参见参考文献2。

2、怎样在不停止程序的情况下替换so文件,并且保证程序不会崩溃?

答案是采用“rm+cp” 或“mv+cp” 来替代直接“cp” 的操作方法。

在用新的so文件 替换旧的so文件 lib 时,如果采用如下方法:

rm lib

cp lib

采用这种方法,目标文件 lib 的 inode 其实已经改变了,原来的 lib 文件虽然不能用 ”ls”查看到,但其 inode 并没有被真正删除,直到内核释放对它的引用。同理,mv只是改变了文件名,其 inode 不变,新文件使用了新的 inode。这样动态链接器 仍然使用原来文件的 inode 访问旧的 so 文件。因而程序依然能正常运行。 
到这里,我们回想在上线操作中在替换可执行程序时,为什么直接使用“cp new old”这样的命令时,系统会禁止这样的操作,并且给出这样的提示“cp: cannot create regular file `old': Text file busy”。这时,我们采用的办法仍然是用“rm+cp”或者“mv+cp”来替代直接“cp”,这跟以上提到的so文件的替换有同样的道理。 
但是,为什么系统会阻止 cp 覆盖可执行程序,而不阻止覆盖 so 文件呢?这是因为 Linux 有个 Demand Paging 机制,所谓“Demand Paging”,简单的说,就是系统为了节约物理内存开销,并不会程序运行时就将所有页(page)都加载到内存中,而只有在系统有访问需求时才将其加载。 
“Demand Paging”要求正在运行中的程序镜像(注意,并非文件本身)不被意外修改,因此内核在启动程序后会锁定这个程序镜像的 inode。对于 so 文件,它是靠 加载的,而毕竟也是用户态程序,没有权利去锁定inode,也不应与内核的文件系统底层实现耦合。

网址:Linux环境下,在不停止程序的情况下,更换动态链接库 https://klqsh.com/news/view/139671

相关内容

驱动程序和下载常见问题
Linux speedtest
洛雪音乐助手最新版下载
揭秘Zigbee设备驱动程序编写:轻松入门与实战技巧
高效利用Linux命令行在线收听网络广播电台
Linux ed命令
快速了解Linux中的网速测试命令! – Linux命令大全(手册)
兴业基金张超:以乐观主义心态挖掘不同市场环境下的投资机会
社交圈子小程序源码 宠物交流兴趣交友平台系统定制 社交圈子论坛小程序开发
巧妙应对停电情况,家庭紧急情况4大应对技巧!

随便看看