Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux下可以替换运行中的程序么?

Linux下可以替换运行中的程序么?

作者头像
一见
发布于 2018-08-07 06:56:10
发布于 2018-08-07 06:56:10
6.7K00
代码可运行
举报
文章被收录于专栏:蓝天蓝天
运行总次数:0
代码可运行

今天被朋友问及“Linux下可以替换运行中的程序么?”,以前依稀记得Linux下是可以的(而Windows就不让),于是随口答道“OK”。结果朋友发来一个执行结果:(test正在运行中)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# cp test2 test
cp: cannot create regular file `test': Text file busy

看起来是程序被占用,无法覆盖。于是自己又再做了几个实验:

(1)先rm删除正在运行的test,然后cp test2 test就没有错误了。 (2)先mv改名正在运行的test,然后cp test2 test也没有问题。

查了查资料并动手分析了一下,找到了比较满意的解释。cp并不改变目标文件的inode,事实上它的实现是这样的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# strace cp test2 test  2>&1 | grep open.*test
open("test2", O_RDONLY|O_LARGEFILE)     = 3
open("test", O_WRONLY|O_TRUNC|O_LARGEFILE) = 4

我原以为cp的实现是“rm + open(O_CREAT)”,不过现在想想上面的实现方式才是最可靠的(保证了时序安全和目标文件的属性)。这也可以解释为什么cp的目标文件会继承被覆盖文件的属性而非源文件。

Linux由于Demand Paging机制的关系,必须确保正在运行中的程序镜像(注意,并非文件本身)不被意外修改,因此内核在启动程序后会锁定这个程序镜像的inode。这就是为什么cp在用“O_WRONLY|O_TRUNC”模式open目标文件时会失败。而先rm再cp的话,新文件的inode其实已经改变了,原inode并没有被真正删除,直到内核释放对它的引用。同理,mv只是改变了文件名,其inode不变,新文件使用了新的inode。

问题到这里已经水落石出,不过刨根究底的个性驱使我再做了以下一组实验,没想到结果完全出乎我意料之外!

写了一个简单的测试程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include 

int main(int argc, char * argv[])
{
    foo();  // An export function by libtest.so.
    sleep(1000);
    return 0;
}

foo()是另一个测试动态库libtest.so的导出接口,只打印一行提示就返回。接下来我把上面对执行文件的测试用例对动态库又做了一遍:

(1)cp libtest2.so libtest.so可以直接覆盖已加载的动态库。 (2)先rm删除已加载的libtest.so,然后cp libtest2.so libtest.so成功。 (3)先mv改名已加载的libtest.so,然后cp libtest2.so libtest.so成功。

除了第一个用例外,结果相同。这样看来,动态库被加载时难道ld并没有锁定inode?不过想想也可以宽恕,毕竟ld也是用户态程序,没有权利去锁定inode,也不应与内核的文件系统底层实现耦合。

到这里都还算在情理之中,看起来Linux也都处理的很好。不过还剩下一个问题:动态库被以cp的方式覆盖后难道不会和Demand Paging机制产生冲突?

在思考这个问题的过程中,我意识到前面这个测试程序的一个致命漏洞,稍作修改如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include 

int main(int argc, char * argv[])
{
loop:
    foo();  // An export function by libtest.so.
    sleep(1);
    goto loop;
    return 0;
}

这次,再执行上面的三个用例后发现,“cp libtest2.so libtest.so”虽然仍可直接覆盖已加载的动态库,但是测试程序马上出现了“Segmentation fault”。而后两个用例结果不变。由此可见,想要安全的替换已加载的动态库,还是用“笨拙”的“rm + cp”吧,看似捷径的“cp覆盖”会直接葬送掉你的程序……

看来,我再一次低估了Linux的健壮性,看似符合逻辑的流程也可能会带来灾难性的后果;“rm & cp”与“cp覆盖”背后所隐藏的底层差异却可以成为你的救星。Linux用得越久越是让人觉得这是一块充满了荆棘和陷阱的原始丛林,只有步步为营实踏前行才能走的更远。

注:以上实验基于SuSE Linux Enterprise Server 9 SP1(Linux 2.6.5 & glibc 2.3.3)。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2009/01/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
linux动态库和静态库
http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520101023104745738/
bear_fish
2018/09/20
13.1K0
一个Linux 动态库常见bug
对于正在运行的程序,当更新动态库尝试重新加载时,可能会导致程序 CoreDump 。
changan
2021/01/18
1.9K0
【读懂Linux】基础IO
操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问:
小文要打代码
2024/10/22
2180
【读懂Linux】基础IO
linux中的ldd命令简介
在linux中, 有些命令是大家通用的, 比如ls, rm, mv, cp等等, 这些我觉得没有必要再细说了。 而有些命令, 只有开发人员才会用到的, 这类命令, 作为程序员的我们, 是有必要了解的, 有的甚至需要熟练使用。
全栈程序员站长
2022/08/10
4.4K1
【Linux】动静态库(超详细)
💢 由于CentOS 8系统2021年12月31日已停止维护服务,CentOS 7系统将于2024年06月30日停止维护服务。CentOS官方不再提供CentOS 9及后续版本,不再支持新的软件和补丁更新。CentOS用户现有业务随时面临宕机和安全风险,并无法确保及时恢复。
IsLand1314
2024/11/19
2350
【Linux】动静态库(超详细)
动态库的制作与两种使用方式你掌握了吗?
在《如何制作属于自己的静态库》中简单介绍了静态库的制作方法,但实际上动态库的使用更为广泛,至于原因,在《静态库和动态库的区别》一文中已有说明。本文介绍动态库的制作方法以及两种使用方式。
编程珠玑
2019/07/22
1.6K0
【在Linux世界中追寻伟大的One Piece】IO基础
操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问,先来直接以代码的形式,实现和上面一模一样的代码:
枫叶丹
2024/09/07
1510
【在Linux世界中追寻伟大的One Piece】IO基础
linux编译so库「建议收藏」
以一个例子来说明。 这里有三个so_test.h, test_a.c, test_b.c
全栈程序员站长
2022/09/07
3.8K0
【Linux篇】革新编程方式:如何开发让人眼前一亮的库
库(Library)是指一组已封装、可复用的代码集合,通常以函数、类或模块的形式提供。它将常见或复杂的功能抽象出来,供开发者直接调用,而无需重复实现。根据链接方式,可分为静态库(在编译时合并到可执行文件)和动态库(在运行时加载);根据用途,又可细分为通用工具库、领域专用库等。通过引入库,项目能够保持结构清晰、降低耦合、加快开发速度,同时也便于维护和升级。
熬夜学编程的小王
2025/04/15
1000
【库函数】Linux下动态库.so和静态库.a的生成和使用
我在路径/root/host/my_program/asoc/include下创建四个文件
SarPro
2024/04/25
2.4K0
【库函数】Linux下动态库.so和静态库.a的生成和使用
【Linux】探索文件I/O奥秘,解锁软硬链接与生成动静态库知识
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针,那什么是FILE类型呢?这是C标准库自己封装的一个结构体。
用户11316056
2024/10/16
1500
【Linux】探索文件I/O奥秘,解锁软硬链接与生成动静态库知识
Linux系统-基础IO
Linux基础IO 零、前言 一、C语言文件IO 1、C库函数介绍 2、stdin/stdout/stderr 二、系统文件IO 1、系统调用介绍 2、系统调用和库函数 三、文件描述符 1、open返回值 2、fd分配规则 四、重定向 1、概念及演示 2、dup2系统调用 3、重定向的原理 4、缓冲区和刷新策略 五、文件及文件系统 1、FILE 2、文件系统 3、软硬链接 六、动静态库 1、制作使用静态库 2、制作使用动态库 零、前言 本章主要讲解学习Linux基础IO流的知识 一、C语言文件IO 1
用户9645905
2022/11/30
1.5K0
Linux系统-基础IO
Linux下库文件制作方法详解
-c create的意思 -r replace的意思,表示当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
Linux兵工厂
2023/02/28
2.3K0
Linux下库文件制作方法详解
Linux 中的静态库和动态库简介及生成过程示例
Linux中的静态库和动态库简介及生成过程示例 【文章摘要】 在实际的软件开发项目中,不是每一行代码都需要我们亲自写。在我们的软件产品中,有一些代码(尤其是函数)的出现频率很高,它们可以被当作公共代码来反复使用。为了避免重复劳动,我们就把这些公共代码编译为库文件,供需要的程序调用。在Linux中,库分为静态库和动态库两种。 本文对静态库和动态库进行了详细的介绍,并用实际的C代码演示了这两种库的生成过程。 一、静态库和动态库简介 众所周知,程序一般需要经过预处理、编译、汇编和链接这几个步骤才能变成可执行的程
用户2017109
2018/06/19
1.6K0
【Linux】动静态库
静态库是一种在编译阶段将库文件的内容直接整合到目标程序中的库文件形式。使用静态库后,库的代码会成为可执行文件的一部分,运行时不需要依赖外部库。
用户11305458
2025/01/09
3220
【Linux】动静态库
linux下的 lib文件的学习思考
某日开发说,一台测试用虚机可以PING通SSH不能连了。运维同学就赶紧去查,SSHD_CONFIG配置文件都正确啊,一点错误都没有,那为什么呢?
孙杰
2019/10/29
2.9K0
linux下的 lib文件的学习思考
【Linux】基础I/O>文件系统&&软硬链接&&动静态库详解
操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问,先来直接以代码的形式,实现和上面一模一样的代码
用户10925563
2024/06/04
1970
【Linux】基础I/O>文件系统&&软硬链接&&动静态库详解
Linux基础IO全面介绍
原文:https://blog.csdn.net/AI_ELF/article/details/122547439
入门笔记
2022/06/03
4570
Linux基础IO全面介绍
【Linux】文件操作、系统IO相关操作、inode和输入输出重定向
C语言中文件操作,在操作一个文件之前我们首先要打开它,那么在学了一段时间操作系统后,你知道在操作一个文件之前为什么要先打开吗? 文件存储在磁盘上,CPU执行进程访问文件,而CPU不能直接访问磁盘,所以对于存储在磁盘上的文件如果要被进程访问,首先应该加载到内存中,所以打开文件的过程就是将文件从磁盘加载到内存。
_小羊_
2025/01/24
1860
【Linux】文件操作、系统IO相关操作、inode和输入输出重定向
【一站式解惑】Linux中.a、.so和.o文件以及-I,-L,LIBRARY_PATH,LD_LIBRARY_PATH等
在说明Linux的.a、.so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系。
自学气象人
2023/01/13
6K0
相关推荐
linux动态库和静态库
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验