前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >程序运行的时候替换程序文件会影响进程吗?

程序运行的时候替换程序文件会影响进程吗?

作者头像
233333
发布2022-05-10 14:05:54
6110
发布2022-05-10 14:05:54
举报
文章被收录于专栏:linux驱动个人学习

我要升级一个程序,在程序运行的时候用新的程序文件替换旧的程序文件,然后杀死进程,重新启动程序。在程序运行的时候替换程序文件,会导致进程出现异常吗?

调用系统调用execve()装载ELF文件的时候,函数load_elf_binary()为主程序的代码段和数据段创建私有的文件映射,为动态链接器的代码段和数据段创建私有的文件映射。动态链接器加载主程序依赖的共享库的时候,调用函数mmap()为共享库的代码段和数据段创建私有的文件映射。

内核为每个文件创建一个页缓存。进程读代码段或者数据段中的某一页的时候,直接把文件的页缓存中的物理页映射到进程的虚拟地址空间,当进程修改这一页的时候,就会生成页错误异常,页错误异常处理程序为文件的页缓存中的物理页生成一个副本,然后把虚拟页映射到这个副本,和文件脱离关系。进程没有修改的虚拟页,直接映射到文件的页缓存中的物理页,如果修改文件的这一页,那么进程可以看到,会影响进程。

第1种替换方法:打开旧的程序文件,使用函数ftruncate()把文件截断到长度为0,然后把新的程序文件复制过来。

直接修改程序文件对进程有影响,假设进程正在函数func1()里面调用函数func2()的时候替换程序文件,函数func2()的位置变化,那么会跳转到一个未知的地方,导致进程出现异常。

第2种替换方法:使用函数unlink()删除旧的程序文件,重新创建文件,然后把新的程序文件复制过来。

假设程序文件是“/sbin/test.elf”,属于EXT4文件系统。glibc库的函数unlink()调用系统调用unlink(),系统调用unlink()的处理过程如下。

(1)修改存储设备上的EXT4文件系统:从父目录“sbin”的数据中删除文件“test.elf”对应的目录项;把文件“test.elf”的索引节点中的硬链接计数减1,如果文件“test.elf”只有一个硬链接,也就是只有一个名称,那么硬链接计数变为0,把索引节点插入到孤儿链表。

(2)文件“test.elf”在内存中的dentry结构体,把它从散列表删除,把它的引用计数减1,因为引用计数大于0,所以没有释放dentry结构体,没有真正删除文件。

删除一个文件的时候,如果某个进程已经打开这个文件,那么删除的结果是:从父目录删除这个文件对应的目录项,把文件的索引节点中的硬链接计数减到0,但是没有删除文件自身。如果进程一直打开这个文件,直到设备断电,就会造成存储设备上文件的索引节点和数据块泄漏。为了解决这个问题,EXT4文件系统使用孤儿链表,超级块的字段s_last_orphan保存孤儿链表的第一个索引节点的编号,ext4_inode结构体的字段i_dtime(删除时间)被重用为保存下一个孤儿索引节点的编号。设备重启以后,挂载EXT4文件系统的时候,如果孤儿链表不是空的,那么释放孤儿链表中的每个索引节点。

当杀死进程的时候,关闭文件“test.elf”,把内存中的dentry结构体的引用计数减1,引用计数变为0,于是释放dentry结构体,释放dentry结构体的过程中把inode结构体的引用计数减1,引用计数变为0,处理如下。

(1)因为索引节点中的硬链接计数是0,所以修改存储设备上的EXT4文件系统:把文件截断到长度为0,释放数据块;把文件从孤儿链表删除;释放索引节点。

(2)释放内存中的inode结构体。

在EXT4文件系统中,旧的程序文件和新的程序文件使用不同的索引节点编号,是2个不同的文件。这种替换方法对进程没有影响。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档