linux 热替换so文件
热替换so文件
www.zhaoch.top > 操作系统 > linux
发现nginx的动态模块无法热更新,于是研究了一下相关的问题。
代码准备
reload.c, 启动文件,用来模拟正在运行的程序,不断重建加载so.so文件
#include <dlfcn.h> #include <stdio.h> typedef void (*F)(); int my_dlopen() { void* h = dlopen("so.so", RTLD_NOW|RTLD_GLOBAL); if (!h) { fprintf(stderr, "%s\n", dlerror()); return 1; } F f = (F)dlsym(h, "action"); f(); return 0; } int main(int argc, char const *argv[]) { printf("start...\n"); while (1) { printf("run\n"); if (my_dlopen() != 0) { return 1; } sleep(2); } return 0; }
so1.c 模拟其中一个so文件
#include <stdio.h> void action() { printf("11111111111111111\n"); }
so2.c 模拟其中另一个so文件,接口相同,打印内容不同
#include <stdio.h> void action() { printf("222222222222222222222\n"); }
编译
gcc reload.c -ldl -o reload gcc -fPIC -shared so1.c -o so1.so gcc -fPIC -shared so2.c -o so2.so
注意
所有的实验需要 export LD_LIBRARY_PATH=./
第一次尝试,直接cp替换
先将 so1.so 设置成默认的 so文件
cp so1.so so.so
启动程序, 然后执行 cp so2.so so.so
./reload start... run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111 <-- 执行 cp so2.so so.so run [1] 38314 segmentation fault (core dumped) ./reload
程序直接崩溃
同时测试了下,rm so.so
并不影响执行,但是停止程序再启动显示so.so: cannot open shared object file: No such file or directory
这个可能说明,so文件被打开一次后句柄并不会关闭,下次打开任然用这个句柄。只是重新读取文件。cp 改变文件内容,并不改变文件inode。
先rm再cp
cp so1.so so.so ./reload start... run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111 <-- rm so.so;cp so2.so so.so run 11111111111111111 run 11111111111111111 run 11111111111111111
结果就是更新无效,猜想还是句柄没关闭的原因。rm的后,程序还指向原来的文件(这个文件外界看不到), cp产生了一个新的文件,程序根本没有理睬这个文件。
dlclose 再加载
在代码中加入 dlclose(h),如下:
int my_dlopen() { void* h = dlopen("so.so", RTLD_NOW|RTLD_GLOBAL); if (!h) { fprintf(stderr, "%s\n", dlerror()); return 1; } F f = (F)dlsym(h, "action"); f(); dlclose(h); // <-- return 0; }
这次可以了
./reload start... run 11111111111111111 run 11111111111111111 run 11111111111111111 run 11111111111111111 <-- cp so2.so so.so run 222222222222222222222 run 222222222222222222222 run 222222222222222222222 run 222222222222222222222
说明确实时句柄的问题,这里涉及到linux inode的问题。每个文件都会对应一个inode, 内部都是按照inode来处理的,同一个文件名的不一定是同一个inode。一个文件只有在没有任何引用的时候才被删除,当程序打开一个so文件,这个文件就被引用了,即使外部删除这个文件,程序还是在使用这个so文件,这个文件只有在程序关闭时才被系统回收。cp过来时个全新的文件,只是文件名相同,inode并不相同,其实程序还是用着老的so文件。dlclose恰恰时关闭了这个文件,之后再次按文件名打开就是新的文件。
备注
看了下nginx的代码,貌似先dlopen之后再close旧的handle,这样是无法热更新的,不太清楚处于什么考虑。
The End
- My github location
- View Source of this website GhostZch.github.io
- Commit issues to discuss with me and others
linux 热替换so文件的更多相关文章
- linux 批量替换所有文件中包含的字符串
sed -i "s/原来字符串/新字符串/g" `grep 原来字符串 -rl .` 格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 ...
- linux批量替换指定文件夹中所有文件的指定内容
命令:sed -i "s#https#http#g" `grep http -rl VEROMODA` 功能:用来替换当前目录VEROMODA文件夹及子文件夹中所有文件中的http ...
- Linux命令行批量替换多文件中的字符串【转】
Linux命令行批量替换多文件中的字符串[转自百度文库] 一种是Mahuinan法,一种是Sumly法,一种是30T法分别如下: 一.Mahuinan法: 用sed命令可以批量替换多个文件中的字符串. ...
- Java_类的热替换
转自:http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/#ibm-pcon Java ClassLoader 技术剖析 在本文中,我们 ...
- Linux中环境变量文件及配置
Linux中环境变量文件及配置 一.环境变量文件介绍 转自:http://blog.csdn.net/cscmaker/article/details/7261921 Linux中环境变量包括系统 ...
- 【转】class卸载、热替换和Tomcat的热部署的分析
这篇文章主要是分析Tomcat中关于热部署和JSP更新替换的原理,在此之前先介绍class的热替换和class的卸载的原理.一 class的热替换ClassLoader中重要的方法 loadClass ...
- class卸载、热替换和Tomcat的热部署的分析
一 class的热替换 ClassLoader中重要的方法 loadClassClassLoader.loadClass(...) 是ClassLoader的入口点.当一个类没有指明用什么加载器加载的 ...
- Java 类的热替换---转载
构建基于 Java 的在线升级系统 Java ClassLoader 技术剖析 在本文中,我们将不对 Java ClassLoader 的细节进行过于详细的讲解,而是关注于和构建在线升级系统相关的基础 ...
- Linux中重命名文件
linux下重命名文件有两种方式: 1.较简单的处理命令:mv mv 原文件名 新文件名 如:mv myFile newName 将MyFile重命名为newName. 2.linux提供了一个重命名 ...
随机推荐
- C语言学习之第一个程序
#include<stdio.h> int main() { printf("This is my first program!\n"); ; } 基本格式大致如下: ...
- 【Spring实战】—— 15 Spring JDBC模板使用
前一篇通过对传统的JDBC的使用操作,可以体会到使用的繁琐与复杂,套句话说,是用了20%作了真正的工作,80%作了重复的工作. 那么通过本篇,可以了解如下的内容: 1 如何配置数据源 2 如何在spr ...
- java之大文件断点续传
针对某些场景下,面对服务文件大,或者服务端服务器不稳定时使用该模块.功能代码如下: import java.io.File; import java.io.FileOutputStream; impo ...
- OC static 和函数
#include <stdio.h> // 定义一个one函数 // 完整地定义一个外部函数需要extern关键字 //extern void one() { // printf(&quo ...
- 在Hibernate单向一对多关联关系中的org.hibernate.StaleStateException 异常。
具体异常如下: Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count fro ...
- QT隐含共享类 QSharedData QSharedDataPointer
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/davidsu33/article/details/28857391 QT中非常多类都实现了隐含共享比 ...
- DateTime小综合
实现效果: 关键知识: 1>DateTime类的ToString()方法: 2>DateTime类的IsLeapYear(); 3>DateTime类的DaysInMomth(); ...
- 学习换脸:Switching Eds: Face swapping with Python, dlib, and OpenCV
学习GitHub上比较火换脸博客,原英文版:https://matthewearl.github.io/2015/07/28/switching-eds-with-python/ 系统win10,x6 ...
- Graphics Card Notes | 烧卡日记(显卡常识笔记)
[ a comparison of several popular Graphics cards ]
- Laravel5 打印SQL
在src/Illuminate/Database/Connection.php里打印SQL默认是关闭的,见https://github.com/laravel/framework/commit/e0a ...