一种C++代码不中断运行更新方法及计算机系统技术方案

技术编号:35156979 阅读:24 留言:0更新日期:2022-10-12 17:14
本发明专利技术公开了一种C++代码不中断运行更新方法及计算机系统。该方法通过在待更新的C++程序中增设一个协议处理函数,利用进程间通信机制,通过请求

【技术实现步骤摘要】
一种C++代码不中断运行更新方法及计算机系统


[0001]本专利技术公开了一种C++代码不中断运行更新方法及计算机系统,涉及计算机运行代码更新领域。通过本专利技术提供的技术方案实现C++可执行程序在不停止运行/不重启的前提下,更新其中的功能函数并即时生效;尤其适用于更新服务器上正在运行、对外提供服务的C++可执行程序。

技术介绍

[0002]开发服务器运行程序时、为追求最好的性能一般会采用C++语言。为了实现开发的C++程序在运行时热更新、并且不停止对外提供服务,通常还会搭配其它脚本语言来进行开发和部署。虽然脚本可以热更新、但是如果运行的C++程序本身的功能逻辑有修改,对该C++程序更新时就需要重启服务器。而重启服务器会造成客户端连接的中断,重启时服务器进行数据/程序初始化也需要一定的时间;重启完成后、客户端重新连接服务器,往往需要再进行一次鉴权。如果服务器重启前连接的客户端较多(比如有五六千个),这些客户端在服务器重启完成后都将重新连接该服务器,这种情况下重启服务器成本太高,会对该服务器提供的服务、处理的业务会造成很大的影响。
[0003]为了避免在更新服务器中运行的程序代码时重启服务器,有些开发人员会增加脚本的比重,甚至以纯脚本的形式来开发服务器运行的程序。这种方式随着后期代码量的不断增多,服务器的性能会有明显的下降;特别是在运营两到三年后,随着服务器上的业务逻辑的不断增加而连接的客户端的数量并没有下降,服务器对外提供业务处理的性能将会受到严重影响。此时、由于之前采用脚本编写的辑辑太多,若再去采用C++重写、将带来的非常高的开发成本。
[0004]为了解决服务器运行程序更新时存在的上述问题/不足,使运行的C++代码也能进行热更新成为程序开发人员经常采用的程序开发指导方向。若实现热更新服务器运行的C++程序,服务器不需要重启、客户端也就不需要重新连接而且能够保留C++代码的优越性能。
[0005]目前用于对运行的C++程序代码进行热更新的方法,包括以下两种:
[0006]1.修改got表来实现热更新:这种方法需要把现有的C++源代码先编译成一个动态库,然后再编译一次这个源代码;把所述动态库隐式引用到第二编译成的可执行代码中。这种方法更新前要编译两次,并且需要打开进程的内存模块信息、解析ELF文件头遍历elf文件的节区表以获取相应的got表。
[0007]2.另起一个进程直接修改代码段:这种方式需要遍历内存页的方式去寻找要替换的函数,通过另起一个进程调用Linux系统的ptrace函数将新的代码附加到需要修改的进程中。这种方法需要保存要修改进程的寄存器且需要恢复寄存器现场;并且调用ptrace函数会导致目标进程暂停,如果暂停时间较长会对原C++程序执行进程的逻辑产生影响。
[0008]以上两种方式都可以达到热更新C++代码的目的。但仍然存在一定的缺点:第一种需要编译两次,找到got表和got表里面的函数地址操作比较复杂;第二种另起一个进程的操作成本比较高且遍历内存页耗时严重,且调用ptrace函数会导致目标进程暂停。

技术实现思路

[0009]针对传统方案存在的上述不足,本专利技术提供一种C++代码不中断运行更新方案。该方案通过预设的协议处理函数实现采用所述动态库中新函数代替待更新C++程序中相应旧函数在所述C++程序运行时执行;实现在不重启服务器,不中断服务器与客户端的连接的基础上,对所述服务器上运行C++程序的进行热更新。
[0010]本专利技术的目的通过如下技术方案来实现:
[0011]一种C++代码不中断运行更新方法,所述方法包括:将用于代替运行的C++程序中的旧函数、且与该旧函数同名的新函数编译到一个动态库中;对所述C++程序增设一个支持其采用所述动态库进行热更新的协议处理函数;在运行所述C++程序的计算机中启动一个进程,该进程接收到热更新所述C++程序的请求时调用所述协议处理函数实现采用所述动态库中、与指定旧函数同名的新函数来代替正在运行的所述C++程序中的所述指定旧函数执行。优选地、在编译所述动态库时所采用的编译环境与编译所述C++程序的编译环境相同。
[0012]其中、所述协议处理函数实现为:根据预设的路径查找并加载用于代替所述旧函数执行的动态库,在内存中的所述C++程序的可执行文件中找到所述旧函数的地址,然后修改代码段、在所述地址处填入机器码使处理器在执行到所述机器码时跳转到所述动态库中与所述旧函数同名的新函数处执行,执行完后返回内存中所述旧函数的下一个地址处继续执行。所述协议处理函数包括两个参数:所述C++程序中旧函数的名称,以及包含代替所述旧函数执行、与所述旧函数同名的新函数的动态库的名称;所述两个参数的取值在所述请求中指定。
[0013]进一步地、所述C++程序在Linux操作系统中执行,所述旧函数的名称为所述旧函数在该C++程序的动态符号表中对应的符号名字。其中、所述动态符号表为所述C++程序在Linux的编译环境中采用g++编译器进行编译时,增加编译选项

rdynamic和

g生成的。可以通过调用Linux系统的dlsym函数找到在该C++程序的可执行文件中、所述旧函数的符号名字的内存地址A;调用所述dlsym函数获取在所述加载的动态库中、所述符号名字的内存地址B。
[0014]进一步地、所述修改代码段、在所述地址处填入机器码、使处理器在执行到所述机器码时跳转到所述动态库中与该旧函数同名的新函数处执行,具体为:调用Linux系统提供的mprotect函数把所述地址A所在的内存页及其后紧邻的一个内存页的保护标记设置为可写。在相关内存可写后,调用Linux操作系统的相关函数(例如函数memset和memcpy)把汇编指令mov rax B和jmp rax对应的机器码依次写入所述地址A开始的内存中后、把所述两个内存页的保护标记修改为只读;其中所述rax为寄存器名称。
[0015]与上述方法相对应、本专利技术还提供一种C++代码不中断运行更新的计算机系统,其特征在于,所述计算机系统采用上述C++代码不中断运行更新方法对其上运行的所述C++程序的可执行文件进行函数更新。优选地、所述计算机系统为通过运行所述C++程序对连接的客户端提供服务。
附图说明
[0016]图1为本专利技术提供的C++代码不中断运行更新方法的流程示意图。
具体实施方式
[0017]为了使本专利技术所解决的技术问题、技术方案以及有益效果更加清楚明白,以下结合附图对本专利技术进行进一步详细说明。应该理解,此处所描述的具体实施例仅仅用以解释本专利技术,并不用于限定本专利技术。
[0018]如图1所示、本专利技术提供一种C++代码不中断运行更新方法,该方法包括以下步骤:
[0019]a.将用于代替运行的C++程序中的旧函数、且与该旧函数同名的新函数编译到一个动态库(也叫动态链接库)中。在编译该动态库时为了避免由于编译环境差异造成的可能的不兼容情况,优选地、在编译所述动态库时所采用的编译环境与所述C++程序编译环境相本文档来自技高网
...

【技术保护点】

【技术特征摘要】
1.一种C++代码不中断运行更新方法,其特征在于,所述方法包括:将用于代替运行的C++程序中的旧函数、且与该旧函数同名的新函数编译到一个动态库中;对所述C++程序增设一个支持其采用所述动态库进行热更新的协议处理函数;在运行所述C++程序的计算机中启动一个进程,该进程接收到更新所述C++程序的请求时、调用所述协议处理函数实现采用所述动态库中、与指定旧函数同名的新函数来代替正在运行的所述C++程序中的所述指定旧函数进行执行。2.如权利要求1所述的方法,其特征在于,在编译所述动态库时所采用的编译环境与编译所述C++程序的编译环境相同。3.如权利要求1或2所述的方法,其特征在于,所述协议处理函数包括两个参数:所述C++程序中旧函数的名称,以及包含代替所述旧函数执行、与所述旧函数同名的新函数的动态库的名称;所述两个参数的取值在所述C++程序函数更新请求中进行指定。4.如权利要求3所述方法,其特征在于,所述协议处理函数具体实现为:加载用于代替所述旧函数执行的动态库;在内存中的所述C++程序的可执行文件中找到所述旧函数的地址,然后修改代码段、在所述地址处填入机器码使处理器在执行到所述机器码时跳转到所述动态库中与该旧函数同名的新函数处执行,执行完后返回内存中所述旧函数的下一个地址处继续执行。5.如权利要求4所述方法,其特征在于,所述C++程序在linux操作系统中执行,所述C++程序中旧函数的名称为所述旧函数在动态符号表中的符号名字;其中...

【专利技术属性】
技术研发人员:赵丰果
申请(专利权)人:盛趣信息技术上海有限公司
类型:发明
国别省市:

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1