CN118069403A - 一种异常指令的处理方法 - Google Patents
一种异常指令的处理方法 Download PDFInfo
- Publication number
- CN118069403A CN118069403A CN202410466612.3A CN202410466612A CN118069403A CN 118069403 A CN118069403 A CN 118069403A CN 202410466612 A CN202410466612 A CN 202410466612A CN 118069403 A CN118069403 A CN 118069403A
- Authority
- CN
- China
- Prior art keywords
- instruction
- reserved area
- signal processing
- processing function
- kernel
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
- 230000002159 abnormal effect Effects 0.000 title claims abstract description 223
- 238000003672 processing method Methods 0.000 title abstract description 7
- 238000012545 processing Methods 0.000 claims abstract description 322
- 238000000034 method Methods 0.000 claims abstract description 161
- 238000004088 simulation Methods 0.000 claims abstract description 75
- 230000006870 function Effects 0.000 claims description 241
- 238000013507 mapping Methods 0.000 claims description 18
- 238000004590 computer program Methods 0.000 claims description 14
- 230000005856 abnormality Effects 0.000 claims description 9
- 230000001960 triggered effect Effects 0.000 claims description 8
- 230000008569 process Effects 0.000 description 31
- 238000010586 diagram Methods 0.000 description 9
- 230000008859 change Effects 0.000 description 7
- 238000012986 modification Methods 0.000 description 6
- 230000004048 modification Effects 0.000 description 6
- 230000009191 jumping Effects 0.000 description 5
- 238000013519 translation Methods 0.000 description 5
- 230000006399 behavior Effects 0.000 description 4
- 230000000694 effects Effects 0.000 description 4
- 230000009471 action Effects 0.000 description 2
- 238000013459 approach Methods 0.000 description 2
- 238000004891 communication Methods 0.000 description 2
- 230000007547 defect Effects 0.000 description 2
- 230000003287 optical effect Effects 0.000 description 2
- 230000003068 static effect Effects 0.000 description 2
- 230000004075 alteration Effects 0.000 description 1
- 230000008901 benefit Effects 0.000 description 1
- 230000002950 deficient Effects 0.000 description 1
- 230000001066 destructive effect Effects 0.000 description 1
- 239000012634 fragment Substances 0.000 description 1
- 238000004519 manufacturing process Methods 0.000 description 1
- 230000007246 mechanism Effects 0.000 description 1
- 230000006386 memory function Effects 0.000 description 1
- 238000007781 pre-processing Methods 0.000 description 1
- 238000012546 transfer Methods 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/07—Responding to the occurrence of a fault, e.g. fault tolerance
- G06F11/0703—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation
- G06F11/0793—Remedial or corrective actions
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/07—Responding to the occurrence of a fault, e.g. fault tolerance
- G06F11/0703—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation
- G06F11/0706—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation the processing taking place on a specific hardware platform or in a specific software environment
- G06F11/0721—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation the processing taking place on a specific hardware platform or in a specific software environment within a central processing unit [CPU]
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/07—Responding to the occurrence of a fault, e.g. fault tolerance
- G06F11/0703—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation
- G06F11/0751—Error or fault detection not based on redundancy
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Quality & Reliability (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Storage Device Security (AREA)
Abstract
本申请提供一种异常指令的处理方法,该方法包括:信号处理函数获取用户程序在运行到异常指令时所对应的第一上下文;将异常指令和第一跳转指令写入第一保留区域;第一保留区域位于用户空间,用于暂存以及执行被模拟的指令;第一跳转指令,位于异常指令之后,用于指示跳转回信号处理函数;修改第一上下文,确定第二上下文;其中,第二上下文中的程序计数器指向第一保留区域的地址;向内核发送第一请求;第一请求用于请求内核使用第二上下文恢复程序执行;在第一保留区域执行完异常指令并得到第一模拟结果后,根据第一跳转指令返回信号处理函数,信号处理函数获取第一模拟结果。该方法,能够实现准确有效地模拟执行异常指令。
Description
技术领域
本申请涉及计算机领域,尤其涉及一种异常指令的处理方法。
背景技术
用户程序在运行过程中,往往由于各种原因,产生不同的异常,比如,用户程序使用了浮点指令以执行浮点类型的运算而硬件却不支持浮点运算导致的异常;再比如,当用户空间耗尽时,将内核空间分配给了用户程序使用,但是由于用户程序缺乏访问内核空间的特权,所以用户程序访问内核空间时,会引发页面异常。这些在执行时引发了异常的指令,又可叫做「异常指令」。
现有技术,对异常的处理方式大多是中止用户程序运行,从而所述异常指令并没有得到成功执行;或者,如果操作系统内核实现了对异常的妥善处理,则异常指令可能被内核模拟执行。但如果操作系统内核尚未实现对应的妥善处理,而这些异常指令又没有对用户程序或者计算机系统造成损坏;或者,这些异常指令是人为设计的,并希望计算机能够正确执行,那么如何处理这些异常指令,有待解决。
发明内容
本申请提供一种异常指令的处理方法,能够实现用户程序准确有效地模拟执行异常指令。
第一方面,本申请实施例提供一种异常指令的处理方法,该方法可以由异常指令的处理装置执行,该异常指令的处理装置可以是一个终端设备或用于终端设备的模块,或者是一个服务器或用于服务器的模块。本申请对该方法的执行主体不做限定。该方法包括:信号处理函数获取用户程序在运行到异常指令时所对应的第一上下文;所述信号处理函数是所述用户程序注册的,用于替换内核对所述异常指令的默认处理方式;所述信号处理函数将所述异常指令和第一跳转指令写入第一保留区域;所述异常指令是基于所述第一上下文获取的;所述第一保留区域位于用户空间,用于暂存以及执行被模拟的指令;所述第一跳转指令,位于所述异常指令之后,用于指示跳转回所述信号处理函数; 所述信号处理函数修改所述第一上下文,确定第二上下文;其中,所述第二上下文中的程序计数器指向所述第一保留区域的地址;所述信号处理函数向所述内核发送第一请求;所述第一请求用于请求所述内核使用所述第二上下文恢复程序执行;在所述第一保留区域执行完所述异常指令并得到第一模拟结果后,根据所述第一跳转指令返回所述信号处理函数,所述信号处理函数获取所述第一模拟结果。
上述方案,一方面,在用户空间设置第一保留区域,可以在第一保留区域执行异常指令,能够使得用户程序模拟执行异常指令,而不会由于异常指令导致用户程序中止运行;另一方面,信号处理函数修改第一上下文,得到第二上下文,第二上下文中程序计数器指向第一保留区域的地址,能够使得内核根据第二上下文正确跳转到第一保留区域执行异常指令;再一方面,将第一跳转指令写入第一保留区域,能够使得异常指令模拟执行完成之后,正确跳转回信号处理函数,并使得信号处理函数能够获取第一模拟结果。
一种可能的实现方法中,内核接收所述用户程序触发的页面异常,并确定所述页面异常的类型为段错误;所述内核触发所述信号处理函数,并将发生页面异常时的第一上下文作为参数发送给所述信号处理函数;所述信号处理函数从所述第一上下文中获取引发页面异常的访存地址,并确定所述访存地址位于内核空间。
上述方案,能够有效处理用户程序访问内核空间带来的页面异常。
一种可能的实现方法中,所述信号处理函数解析所述异常指令,判断所述异常指令是否包括读操作;若所述异常指令包括读操作,且所述读操作对应的访存地址位于内核空间,则所述信号处理函数向内核发送第三请求;所述第三请求用于请求所述内核读数据;所述信号处理函数将所述数据写入第二保留区域;所述第二保留区域位于用户空间,所述第二保留区域用于暂存被模拟的指令所需访问的数据;所述信号处理函数根据所述数据在所述第二保留区域对应的地址,修改所述异常指令和/或所述第一上下文;所述信号处理函数将所述异常指令写入第一保留区域,包括:所述信号处理函数将修改后的所述异常指令写入第一保留区域。
上述方案,在用户空间设置第二保留区域,第二保留区域用于暂存被模拟的指令所需访问的数据;由于用户程序缺乏访问内核空间的特权,当读操作对应的访存地址位于内核空间,可以向内核发送第三请求,请求内核从重定向空间读取数据后,将数据返回给信号处理函数;信号处理函数获取数据后,将数据写入第二保留区域;那么,在第一保留区域执行异常指令时,可以从第二保留区域获取对应的数据,保证用户程序正常执行,因此能够使得用户程序模拟执行访问内核空间的指令。
一种可能的实现方法中,所述信号处理函数解析所述异常指令,判断所述异常指令是否包括写操作;若异常指令包括写操作,且所述写操作对应的访存地址位于内核空间,所述信号处理函数在所述第二保留区域预设一个地址用于所述写操作,并根据预设的地址修改所述异常指令和/或所述第一上下文。
上述方案,能够实现准确有效地处理访存地址位于内核空间的写操作,能够使得用户程序模拟执行访问内核空间的指令。
一种可能的实现方法中,所述信号处理函数解析所述异常指令,判断所述异常指令是否包括写操作;若异常指令包括写操作,且待写入数据对应的内存地址位于所述内核空间,所述信号处理函数从所述第二保留区域获取所述待写入数据;所述信号处理函数向所述内核发送第四请求;所述第四请求,用于请求所述内核将所述待写入的数据写入重定向空间;所述重定向空间指的是与所述内核空间存在映射关系的地址空间。
上述方案,能够实现准确有效地将待写入数据写入重定向空间,能够使得用户程序模拟执行访问内核空间的指令。
一种可能的实现方法中,所述信号处理函数获得第三上下文,所述第三上下文是在所述第一保留区域执行所述异常指令产生的;所述信号处理函数从所述第三上下文中获取所述第一模拟结果。
上述方案,从第三上下文中能够准确快速地获取第一模拟结果。一种可能的实现方法中,所述信号处理函数修改所述第三上下文,确定第四上下文;其中,所述第四上下文中的程序计数器指向所述异常指令的下一条指令;所述信号处理函数向所述内核发送第五请求;所述第五请求,用于请求内核使用所述第四上下文恢复程序执行。
上述方案,在异常指令模拟执行完成之后,能够实现准确有效地执行异常指令的下一条指令,恢复程序执行。
一种可能的实现方法中,所述信号处理函数获取所述用户程序中位于所述异常指令后的N条指令;N为大于等于0的整数;所述信号处理函数将所述异常指令及所述N条指令写入所述第一保留区域;所述信号处理函数将所述第一跳转指令写入第一保留区域;所述第一跳转指令位于所述异常指令和所述N条指令之后。
上述方案,能够实现一次性地模拟执行异常指令及N条指令,提高程序执行效率,减少不必要的上下文切换和信号处理,提升性能。
一种可能的实现方法中,确定所述异常指令为复杂指令;所述复杂指令中包括访存操作及运算操作、多次访存操作或多次运算操作。
上述方案,能够实现准确有效地模拟执行复杂指令。
一种可能的实现方法中,确定所述异常指令为访存指令;所述信号处理函数解析所述异常指令,确定所述异常指令的访存地址位于内核空间;所述信号处理函数确定所述访存地址对应的第一重定向地址;所述第一重定向地址是位于重定向空间的地址;所述信号处理函数向所述内核发送第二请求;所述第二请求用于请求所述内核根据所述第一重定向地址进行数据读写操作;所述信号处理函数获取所述内核的读写结果,模拟执行所述异常指令,得到第二模拟结果。
上述方案,若异常指令为访存指令时,可以不把异常指令写入第一保留区域,而由内核对数据进行读写操作后,再由信号处理函数直接模拟执行所述异常指令。该方案,能够有效地处理访存指令,提高用户程序执行效率。
一种可能的实现方法中,在所述用户程序启动时,设置第一保留区域和第二保留区域;或,
在首次为所述用户程序分配内核空间时,设置第一保留区域和第二保留区域。
上述方案,能够提高分配第一保留区域和第二保留区域的灵活性。
一种可能的实现方法中,分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置不可读不可写不可执行;向所述第一保留区域写入异常指令时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置不可读不可写不可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置可写不可执行。
上述方案,给第一保留区域设置权限,能够增大第一保留区域的安全性;采用不同的方式设置权限,能够提高设置第一保留区域权限的灵活性。
一种可能的实现方法中,分配所述第二保留区域时,将所述第二保留区域对应的权限设置可读可写不可执行;或,
分配所述第二保留区域时,将所述第二保留区域对应的权限设置不可读不可写不可执行;对所述第二保留区域进行读操作或写操作时,将所述第二保留区域对应的权限设置可读可写不可执行;完成对所述第二保留区域读操作或写操作时,将所述第二保留区域对应的权限设置不可读不可写不可执行。
上述方案,给第二保留区域设置权限,能够增大第二保留区域的安全性;采用不同的方式设置权限,能够提高设置第二保留区域权限的灵活性。
第二方面,本申请实施例提供一种异常指令的处理装置,包括:获取单元和处理单元。所述获取单元,用于获取用户程序在运行到异常指令时所对应的第一上下文;所述信号处理函数是所述用户程序注册的,用于替换内核对所述异常指令的默认处理方式;所述处理单元,用于将所述异常指令和第一跳转指令写入第一保留区域;所述异常指令是基于所述第一上下文获取的;所述第一保留区域位于用户空间,用于暂存以及执行被模拟的指令;所述第一跳转指令,位于所述异常指令之后,用于指示跳转回所述信号处理函数; 所述信号处理函数修改所述第一上下文,确定第二上下文;其中,所述第二上下文中的程序计数器指向所述第一保留区域的地址;所述信号处理函数向所述内核发送第一请求;所述第一请求用于请求所述内核使用所述第二上下文恢复程序执行;在所述第一保留区域执行完所述异常指令并得到第一模拟结果后,根据所述第一跳转指令返回所述信号处理函数,所述信号处理函数获取所述第一模拟结果。
一种可能的实现方法中,所述处理单元,用于接收所述用户程序触发的页面异常,并确定所述页面异常的类型为段错误;所述内核触发所述信号处理函数,并将发生页面异常时的第一上下文作为参数发送给所述信号处理函数;所述信号处理函数从所述第一上下文中获取引发页面异常的访存地址,并确定所述访存地址位于内核空间。
一种可能的实现方法中,所述处理单元,用于解析所述异常指令,判断所述异常指令是否包括读操作;若所述异常指令包括读操作,且所述读操作对应的访存地址位于内核空间,则所述信号处理函数向内核发送第三请求;所述第三请求用于请求所述内核读数据;所述信号处理函数将所述数据写入第二保留区域;所述第二保留区域位于用户空间,所述第二保留区域用于暂存被模拟的指令所需访问的数据;所述信号处理函数根据所述数据在所述第二保留区域对应的地址,修改所述异常指令和/或所述第一上下文;所述信号处理函数将所述异常指令写入第一保留区域,包括:所述信号处理函数将修改后的所述异常指令写入第一保留区域。
一种可能的实现方法中,所述处理单元,用于解析所述异常指令,判断所述异常指令是否包括写操作;若异常指令包括写操作,且所述写操作对应的访存地址位于内核空间,所述信号处理函数在所述第二保留区域预设一个地址用于所述写操作,并根据预设的地址修改所述异常指令和/或所述第一上下文。
一种可能的实现方法中,所述处理单元,用于解析所述异常指令,判断所述异常指令是否包括写操作;若异常指令包括写操作,且待写入数据对应的内存地址位于所述内核空间,所述信号处理函数从所述第二保留区域获取所述待写入数据;所述信号处理函数向所述内核发送第四请求;所述第四请求,用于请求所述内核将所述待写入的数据写入重定向空间;所述重定向空间指的是与所述内核空间存在映射关系的地址空间。
一种可能的实现方法中,所述处理单元,用于获得第三上下文,所述第三上下文是在所述第一保留区域执行所述异常指令产生的;所述信号处理函数从所述第三上下文中获取所述第一模拟结果。
一种可能的实现方法中,所述处理单元,用于修改所述第三上下文,确定第四上下文;其中,所述第四上下文中的程序计数器指向所述异常指令的下一条指令;所述信号处理函数向所述内核发送第五请求;所述第五请求,用于请求内核使用所述第四上下文恢复程序执行。
一种可能的实现方法中,所述处理单元,用于获取所述用户程序中位于所述异常指令后的N条指令;N为大于等于0的整数;所述信号处理函数将所述异常指令及所述N条指令写入所述第一保留区域;所述信号处理函数将所述第一跳转指令写入第一保留区域;所述第一跳转指令位于所述异常指令和所述N条指令之后。
一种可能的实现方法中,所述处理单元,用于确定所述异常指令为复杂指令;所述复杂指令中包括访存操作及运算操作、多次访存操作或多次运算操作。
一种可能的实现方法中,所述处理单元,用于确定所述异常指令为访存指令;所述信号处理函数解析所述异常指令,确定所述异常指令的访存地址位于内核空间;所述信号处理函数确定所述访存地址对应的第一重定向地址;所述第一重定向地址是位于重定向空间的地址;所述信号处理函数向所述内核发送第二请求;所述第二请求用于请求所述内核根据所述第一重定向地址进行数据读写操作;所述信号处理函数获取所述内核的读写结果,模拟执行所述异常指令,得到第二模拟结果。
一种可能的实现方法中,所述处理单元,用于在所述用户程序启动时,设置第一保留区域和第二保留区域;或,
在首次为所述用户程序分配内核空间时,设置第一保留区域和第二保留区域。
一种可能的实现方法中,所述处理单元,用于分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置不可读不可写不可执行;向所述第一保留区域写入异常指令时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置不可读不可写不可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置可写不可执行。
一种可能的实现方法中,所述处理单元,用于分配所述第二保留区域时,将所述第二保留区域对应的权限设置可读可写不可执行;或,
分配所述第二保留区域时,将所述第二保留区域对应的权限设置不可读不可写不可执行;对所述第二保留区域进行读操作或写操作时,将所述第二保留区域对应的权限设置可读可写不可执行;完成对所述第二保留区域读操作或写操作时,将所述第二保留区域对应的权限设置不可读不可写不可执行。
第三方面,本申请实施例还提供一种计算设备,包括:
存储器,用于存储程序指令;
处理器,用于调用所述存储器中存储的程序指令,按照获得的程序指令执行实现上述第一方面的任意方法。
第四方面,本申请实施例还提供一种计算机可读存储介质,其中存储有计算机可读指令,当计算机读取并执行所述计算机可读指令时,实现上述第一方面的任意方法。
第五方面,本申请实施例提供了一种计算机程序产品,包括有可由计算机设备执行的计算机程序,当所述程序在计算机设备上运行时,使得所述计算机设备执行实现上述第一方面的任意方法。
附图说明
图1为本申请实施例提供的一种异常指令的处理方法的流程示意图;
图2为本申请实施例提供的一种异常指令的处理方法的流程示意图;
图3为本申请实施例提供的一种异常指令的处理方法的流程示意图;
图4为本申请实施例提供的一种异常指令的处理方法的流程示意图;
图5为本申请实施例提供的一种异常指令的处理方法的流程示意图;
图6为本申请实施例提供的一种异常指令的处理方法的流程示意图;
图7为本申请实施例提供的一种异常指令的处理方法的流程示意图;
图8为本申请实施例提供的一种异常指令的处理装置的结构示意图;
图9为本申请实施例提供的一种异常指令的处理装置的结构示意图。
具体实施方式
下面对本申请使用的部分专业术语进行解释。
内核(Kernel,又称核心):在计算机科学中是一个用来管理软件发出的资料I/O(输入与输出)要求的电脑程序,将这些要求转译为资料处理的指令并交由中央处理器(CPU)及电脑中其他电子组件进行处理,是现代操作系统中最基本的部分。它是为众多应用程序提供对计算机硬件的安全访问的一部分软件,这种访问是有限的,并由内核决定一个程序在什么时候对某部分硬件操作多长时间。直接对硬件操作是非常复杂的。所以内核通常提供一种硬件抽象的方法,来完成这些操作。有了这个,通过进程间通信机制及系统调用,应用进程可间接控制所需的硬件资源(特别是处理器及IO设备)。总结起来,由于用户程序是不可任意信任的,因此涉及到硬件的操作都必须由内核接管,用户程序要进行这样的操作就必须与内核提供的抽象层交互。有时候我们会说「内核态」,强调 CPU 的一种状态,这个状态具有高特权,用于运行内核。实务上这个词和「内核」基本上可以理解为同义词。操作系统大多数时候就是指操作系统内核。
异常、陷阱 (trap) 和中断:程序执行过程中,遇到 CPU 自身不能处理的错误,就会引发异常。异常会使 CPU 陷入内核态,并交由内核处理异常,异常处理后,还会返回用户态。陷阱有时用来指代有意引发的异常,如当用户态程序需要和内核交互时,会通过系统调用(syscall)使得 CPU 陷入内核态以便内核处理来自用户态程序的请求,处理完成后,还会返回用户态。从 CPU 的角度看,异常和陷阱是几乎完全一样的。中断是由外部事件引发的(也就是说,不是 CPU 上执行的程序引发的),这些外部事件通常来自时钟或外部硬件,是不可预期的。中断的到来会使得 CPU 陷入内核态,交由内核处理中断(也就是处理来自外部的请求),处理完成也会返回用户态。许多技术人员,尤其是x86的技术人员,因为这三者有很多实质性共同点,喜欢把这三者都称为「中断」。本申请主要采取MIPS的习惯,异常和陷阱几乎是同义词,中断则是特指外部事件引发的。
用户程序:与内核相对的,运行在「用户态」的程序。也就是我们平常说的「进程」(强调程序正在运行)、「程序」、「软件」。「用户态」,强调 CPU 的一种状态,这个状态不具有特权,可进行的操作受限,用于运行用户程序,实务上这个词和「用户程序」基本上可以理解为同义词。
物理内存/虚拟内存:由于用户程序不应当能够直接访问物理内存(否则其特权就过高了),有必要建立一种映射,让用户程序间接访问物理内存。另一方面,由于操作系统需要能够运行无数个进程,因此也需要这样一层映射让所有程序都能在相同的地址空间上运行。建立映射后,用户程序所使用的内存地址就称作虚拟内存地址或虚拟地址(virtualaddress)。
地址空间:无论是虚拟内存还是物理内存,我们都需要使用内存地址来确定将要访问的具体位置。地址的宽度决定了可访问的最大内存大小。实际上,当我们说一个 CPU是「xx 位」的时候,指的是它的虚拟地址的宽度。而物理地址的宽度(实际上是地址总线的宽度)则不一定和虚拟地址的宽度等同,比如,32 位 CPU 有可能为了支持更大的物理内存(大于 4GiB),使其物理地址大于 32 位;而因为 64 位所能编码的地址空间实在是太大了,可见的未来还无法实现这么大的内存,所以一般来说 64 位 CPU 的物理地址的宽度不会超过 50 位(已经能编码1PiB = 1024 TiB = 1048576 GiB 的物理内存了)。
内核空间/用户空间:虚拟内存被分为内核空间(kernel space)和用户空间(userspace)两个区段。由于内核与用户程序都需要内存才能运行,因此它们都需要占据一定的虚拟内存空间。因此,其实也可以说,内核运行在内核空间上,用户程序运行在用户空间上。内核由于其特权,可以访问用户空间;用户空间由于缺乏特权,访问内核空间将引发异常。两个空间在虚拟内存中占据的大小通常是架构特定的。对于 32 位MIPS指令集架构,内核空间和用户空间均分4GiB 的 32 位虚拟内存空间,其中内核空间分到高2GiB(0x80000000~0xFFFFFFFF),用户空间分到了低 2GiB(0x0~0x7FFFFFFF),且互不重叠。对于 x86,内核空间占用高 1GiB,用户空间占用低 3GiB。下文中,内核空间的映射称其为内核映射,用户空间的映射我们称其为用户映射。内核映射一般来说只有一份,这是因为只能同时运行一个内核。用户映射则是每个进程各自有一个。
内存分页:虚拟内存中最重要的一项技术之一。因为操作系统可以运行无数个进程,这些进程所使用的总内存量可能大于物理内存的容量,因此有必要使用外存(通常是硬盘)来进行交换(swap,又叫分页文件/页面文件 page file 或交换文件 swap file)。因此催生了分页(paging),分页通常实作为页表(page table)。页表的最细粒度为页表项(pagetable entry,PTE,简称为页 page),一页所能管理的内存大小通常是 4KiB,这也是内存管理的最细粒度。页表描述了对于一个特定的进程,其虚拟地址应当被如何映射到物理地址。操作系统为不同的进程建立各自的页表,它们是不共享的(也就是说,同一个用户空间地址,在不同进程的页表中,其映射是不一致的)。页表还描述了,对于一个特定的页,其是否驻留(resident)在内存上。如果一个进程访问了一个不驻留在内存上的分页内的虚拟地址(「缺页」),就会产生页面异常(page fault,常被称为「缺页中断」,这是一个惯用表达,并不是只有缺页才能引发此类异常,因此本申请不采用这个容易引起误解的翻译),导致 CPU进入内核态,由内核将储存在交换中的页读进内存中,然后返回用户态继续执行。
缺页:指用户程序访问了一个不存在有效映射的虚拟地址。缺页需要由内核来修正,上面就讲了其中一种情形,还有一种情形是内存分配后首次访问。并非所有的缺页情形都可被内核修正,比如说,如果用户程序访问的这个虚拟地址所在的页面根本没有被分配,那么就是一种内存误用,应当导致段错误。
地址翻译:由于访存最终都要落实到物理内存之上,从而虚拟地址必须以某种方式被翻译为物理地址。地址翻译其实就是以某种方式解析并查询页表中的地址映射。地址翻译是 CPU 中的内存管理单元 MMU 的职责,它独立或在内核协助下解析并查询页表。页表中可能为页面指定了权限(可读、可写、可执行等),MMU 也要负责在用户程序执行了超出页面权限的操作时,引发页面异常。如果页表中不存在相应的地址映射,或者用户程序访问了内核空间,它也要引发页面异常。但需要注意的是,在内核态时,访问内核空间,是可以正常进行地址翻译的。
内存耗尽(out of memory,OOM,又称「内存溢出」):操作系统(内核)所能提供的最大内存数量是物理内存的大小加上交换的大小。如果它们都接近被分配完,此时还能提供的内存就相当少了,从而导致用户程序的内存申请无法被满足,此时就进入 OOM 状态。此时内核已经走投无路,只能挑选一个占用内存最多的进程,将其杀死,以解除 OOM 状态。前面已经提到,虚拟内存空间分为内核空间和用户空间。一个用户程序所能使用的最大内存空间取决于用户空间的大小,比如在 32 位 MIPS 上是 2GiB。如果这 2GiB 已经全部用完,那么用户程序再向内核申请内存时,即使物理内存和交换都还很充足,内核也无法再给这个程序分配内存了。此时只能给这个进程返回一个错误,让用户程序自行处理(用户程序可能选择退出,也可能选择自行清理已使用的内存)。
段错误(Segment Fault):段错误是一个内核提供给用户程序的抽象。内核将段错误作为一种信号发送给进程。用户程序可以选择自行处理段错误,不过这是非常困难的,所以一般来说程序只能选择立即退出以免造成更严重的后果。基本上,除了缺页以外,其他原因导致的页面异常都是由于某种内存误用(misusage),或者说,属于软件的缺陷,因此都应该导致段错误,并最终导致程序退出。
内存误用:所谓误用,即是指 misusage,意在指代用户程序错误地使用了内存。从结果上讲,内存误用会导致:MMU 引发页面异常 -> 内核处理页面异常 -> 内核认为这个页面异常无法被修正 -> 向程序发送段错误信号。从过程上讲,一般是用户程序:1)访问了内核空间;2)访问了未分配的页面;3)所执行操作不匹配页面权限。
程序计数器(Program Counter,PC):在 x86 的习惯里又叫做 InstructionPointer(指令指针,IP),指的是 CPU 内的一个寄存器,其储存着 CPU 下一条将要执行的指令所在的内存地址(一般来说是虚拟地址)。也就是说,PC 指向的那条指令其实还没有被执行,而是下一步将要执行的。如果没有遇到分支和跳转,PC 的值会随着程序执行单调递增,也就是说,会一直指向当前指令的下一条指令所在的地址;然而,分支和跳转会改变 PC的值,使其不指向当前指令的下一条指令所在的地址,而是指向分支/跳转指令所指定的目的地址(destination)。
异常程序计数器(Exception Program Counter,EPC):这是 MIPS 指令集定义的一个寄存器,但在别的指令集中可能有不同的名字;有的指令集也可能不提供这个寄存器,而是通过在异常处理时自动读写内核栈中的异常帧来实现。这个寄存器储存的是引发异常的那条指令所在的内存地址。也就是说,EPC 指向的那条指令其实相当于还没有被执行,或者说,由于引发了异常,所有状态都被 CPU 自动回滚到这条指令被执行之前的状态(「精确异常」)。这个寄存器的存在有两个意义:1)内核处理异常后常常需要返回原来的位置,CPU在异常返回时就读取这个寄存器并改变 PC;2)有时候内核处理异常会需要改变返回的位置,如trap-and-emulate,常常需要在返回时跳过一条指令,那么内核就修改这个寄存器的值;3)内核经常需要读取 EPC 来确定如何进行异常处理,trap-and-emulate 就是其中一个例子,内核必须读取 EPC 然后读取 EPC 指向的那条指令,才能进一步解析并模拟那条指令,另一个例子是,正如前面所说,内存误用包括页面权限不匹配,其中一种情况就是尝试跳转到不可执行页上的地址,这时候,其实 EPC 会指向跳转后的目的地址,因此,内核只需要判断 EPC 指向的地址所在的页面是否可执行,就知道是不是内存误用了。
trap-and-emulate:为「捕获并模拟」。某些指令执行时,会因为种种原因引发异常而需要内核来处理。通常情况下,这些异常是我们不希望见到的,如果出现,则意味着程序存在缺陷,内核处理异常的最终结果因此常常是破坏性的,如杀死该进程。然而,有一种例外情况,即,我们不希望见到这种异常,但这个异常并非由程序的缺陷引起,而是某种不可抗力引发的。这种情况下,我们会希望程序仍然可以正常运行,此时内核需要对引发异常的指令进行模拟,模拟的结果就如同它被正确执行一样。一种典型的情况就是,出于节省成本的考虑,CPU 中省去了 FPU(浮点运算单元),从而用户程序执行的浮点运算指令将引发异常,此时我们当然希望内核为它模拟这条浮点运算指令。这里 trap 的意思就是指内核捕获异常,emulate 就是指内核在处理异常时,对引发异常的指令进行模拟。trap-and-emulate 是一种对用户态完全透明的模拟,也就是说,用户程序不会知道一条指令是否经过了 trap-and-emulate,也不需要做出任何修改就能受益于它。通常而言,因为引发异常的那条指令已经被内核所模拟,内核在异常返回前,要修改 EPC,使其指向引发异常的那条指令的下一条指令(如果模拟的是分支/跳转指令,那也可能改为跳转的目的地址)。
上下文(context):当一个程序或程序片段在执行中被突然打断,至少需要保存多少信息,在其所占用的资源被内核或其它程序或本程序中的其它片段所使用之后,才能保证在将来完整恢复其执行,这个至少需要保存的信息就是上下文。因此,上下文可以理解为程序执行的背景环境,包含了在特定时刻程序所需的所有信息。
信号(Signal):用来通知进程发生了异步事件。内核可以因为内部事件向进程发送信号,通知进程发生了某个事件。信号除了基本通知的功能外,还可以传递附加信息。收到信号的进程对各种信号有不同的处理方法。其中一类方法为:对该信号的处理保留系统的默认值。这种默认操作,对大部分的信号的来说是使进程终止。进程通过特定的系统调用来指定进程对某个信号的处理行为(换句话说,为某个信号注册signal handler信号处理函数),这样就会覆盖掉默认的处理行为。也就是说,只要进程没有对某个信号注册signalhandler,那么内核就会使用默认行为处理该信号。SIGSEGV信号是系统给程序发送的段错误信号,表示发生了某种内存误用,默认动作为使程序终止。SIGKILL信号是强制杀死程序信号,任何程序都不可以捕捉该信号(也就是说,不能为其注册signal handler),默认动作为程序终止。
图1为本申请实施例提供的一种异常指令的处理方法的流程示意图,该方法可以由异常指令的处理装置执行,该异常指令的处理装置可以是一个终端设备或用于终端设备的模块,或者是一个服务器或用于服务器的模块。本申请对该方法的执行主体不做限定。
该方法包括以下步骤:
步骤101,信号处理函数获取用户程序在运行到异常指令时所对应的第一上下文。
其中,所述信号处理函数是所述用户程序注册的,用于替换内核对所述异常指令的默认处理方式。
一种可能的实现方法中,本申请对异常指令的类型不做限定,比如异常指令可以是引发段错误SIGSEGV的指令,也可以是引发浮点异常SIGFPE的指令,只要该异常指令引发的异常信号能够被信号处理函数捕获即可。本申请在后续实施例的介绍时,均以异常指令为段错误SIGSEGV对应的指令来进行说明,在此不再赘述。
一种可能的实现方法中,在上述步骤101之前,用户程序注册对应的信号处理函数,替换内核对异常指令的默认处理方式。比如,段错误SIGSEGV对应的信号处理函数的默认处理方式是中止用户程序;注册之后的段错误SIGSEGV对应的信号处理函数能够捕获第一上下文,并模拟执行异常执行。
一种可能的实现方法中,所述信号处理函数获取用户程序在运行到异常指令时所对应的第一上下文之前,还包括:内核接收所述用户程序触发的页面异常,并确定所述页面异常的类型为段错误;所述内核触发所述信号处理函数,并将发生页面异常时的第一上下文作为参数发送给所述信号处理函数;所述信号处理函数从所述第一上下文中获取引发页面异常的访存地址,并确定所述访存地址位于内核空间。也就是说,本申请的段错误是由于用户程序访问内核空间触发的,当然,段错误也可以由其他原因触发,比如,页面未分配触发段错误或者用户程序不合乎页面的访问权限触发段错误,本申请对触发段错误的类型不做限定。该方案,能够有效处理用户程序访问内核空间带来的页面异常。
一种可能的实现方法中,当用户空间耗尽时,可以将内核空间分配给用户程序,本申请对分配内核空间的对象不做限定,可以是内核将内核空间分配给用户程序;也可以是,用户程序将内核空间分配给用户程序。
步骤102,信号处理函数将异常指令和第一跳转指令写入第一保留区域。
其中,所述异常指令是基于所述第一上下文获取的;所述第一保留区域位于用户空间,用于暂存以及执行被模拟的指令;所述第一跳转指令,位于所述异常指令之后,用于指示跳转回所述信号处理函数。
一种可能的实现方法中,从上下文中获取异常指令所处的地址,访问该地址获取异常指令。若该地址位于用户空间,则信号处理函数访问该地址获取异常指令;若该地址位于内核空间,则内核访问该地址获取异常指令。
一种可能的实现方法中,在用户空间单独划分一块区域作为第一保留区域,该第一保留区域用于暂存以及执行被模拟的指令。
一种可能的实现方法中,将异常指令写入第一保留区域后,将第一跳转指令写入第一保留区域,第一跳转指令在第一保留区域中的位置在异常指令之后。
一种可能的实现方法中,第一跳转指令包括立即数跳转指令或无条件自陷指令,当然,第一跳转指令也可以为其他类型的指令,本申请对此不做限定,只要根据第一跳转指令能够跳转回信号处理函数即可。
步骤103,信号处理函数修改第一上下文,确定第二上下文。
其中,所述第二上下文中的程序计数器指向所述第一保留区域的地址。
一种可能的实现方法中,修改第一上下文,得到第二上下文,第二上下文中的程序计数器指向第一保留区域的地址,可以使得内核使用第二上下文恢复程序执行时,执行第一保留区域的指令。
步骤104,信号处理函数向内核发送第一请求。
其中,所述第一请求用于请求所述内核使用所述第二上下文恢复程序执行。
步骤105,在第一保留区域执行完异常指令并得到第一模拟结果后,根据第一跳转指令返回信号处理函数,信号处理函数获取第一模拟结果。
一种可能的实现方法中,在第一保留区域执行所述异常指令,并得到所述异常指令的第一模拟结果,然后再执行第一保留区域的第一跳转指令,返回信号处理函数,信号处理函数获得第三上下文,所述第三上下文是在所述第一保留区域执行所述异常指令产生的;所述信号处理函数从所述第三上下文中获取所述第一模拟结果。该方案,从第三上下文中能够准确快速地获取第一模拟结果。
一种可能的实现方法中,所述信号处理函数获取所述第一模拟结果之后,还包括:所述信号处理函数修改所述第三上下文,确定第四上下文;其中,所述第四上下文中的程序计数器指向所述异常指令的下一条指令;所述信号处理函数向所述内核发送第五请求;所述第五请求,用于请求内核使用所述第四上下文恢复程序执行。该方案,在异常指令模拟执行完成之后,能够实现准确有效地执行异常指令的下一条指令,恢复程序执行。
上述方案,一方面,在用户空间设置第一保留区域,可以在第一保留区域执行异常指令,能够使得用户程序模拟执行异常指令 ,而不会由于异常指令导致用户程序的中止运行;另一方面,信号处理函数修改第一上下文,得到第二上下文,第二上下文中程序计数器指向第一保留区域的地址,能够使得内核根据第二上下文正确跳转到第一保留区域执行异常指令;再一方面,将第一跳转指令写入第一保留区域,能够使得异常指令模拟执行完成之后,正确跳转回信号处理函数,并使得信号处理函数能够获取第一模拟结果。
一种可能的实现方法中,在用户空间单独划分一块区域作为第二保留区域,该所述第二保留区域位于用户空间,所述第二保留区域用于暂存被模拟的指令所需访问的数据;
一种可能的实现方法中,在上述步骤102之前,还包括:所述信号处理函数解析所述异常指令,判断所述异常指令是否包括读操作;若所述异常指令包括读操作,且所述读操作对应的访存地址位于内核空间,则所述信号处理函数向内核发送第三请求;所述第三请求用于请求所述内核读数据;所述信号处理函数将所述数据写入第二保留区域;所述信号处理函数根据所述数据在所述第二保留区域对应的地址,修改所述异常指令和/或所述第一上下文。也就是说,在将所述异常指令写入第一保留区域之前,还需判断所述异常指令中读操作对应的访存地址是否位于内核空间,如果位于内核空间,则向内核发送第三请求,请求内核从重定向空间读取数据,并将读取的数据返回给信号处理函数,由信号处理函数将所述数据写入第二保留区域,并根据第二保留区域的地址修改所述异常指令和/或所述第一上下文,比如将所述异常指令所用的寄存器中存放的地址修改为第二保留区域的地址。该方案,在用户空间设置第二保留区域,第二保留区域用于暂存被模拟的指令所需访问的数据;由于用户程序缺乏访问内核空间的特权,当读操作对应的访存地址位于内核空间,可以向内核发送第三请求,请求内核从重定向空间读取数据后,将数据返回给信号处理函数;信号处理函数获取数据后,将数据写入第二保留区域;那么,在第一保留区域执行异常指令时,可以从第二保留区域获取对应的数据,保证用户程序正常执行,因此能够使得用户程序模拟执行访问内核空间的指令。
一种可能的实现方法中,在上述步骤102之前,还包括:所述信号处理函数解析所述异常指令,判断所述异常指令是否包括写操作;若所述异常指令包括写操作,且所述写操作对应的访存地址位于内核空间,则所述信号处理函数在所述第二保留区域预留一个地址用于该写操作,并根据该地址修改所述异常指令和/或所述第一上下文。也就是说,在将所述异常指令写入第一保留区域之前,还需判断所述异常指令是否需要写入数据到重定向空间,如果需要写入数据到重定向空间,则在所述第二保留区域预留一个地址用于该写操作,并根据该地址修改所述异常指令和/或所述第一上下文,比如将所述异常指令中所用的寄存器中存放的地址修改为第二保留区域的地址。该方案,在用户空间设置第二保留区域,第二保留区域用于暂存被模拟的指令写入的数据;由于用户程序缺乏访问内核空间的特权,当用户程序需要写入数据到重定向空间,可以先写入到第二保留区域,然后再由信号处理函数从中取回;信号处理函数获取数据后,后续步骤中还将请求内核写入数据到重定向空间;那么,在第一保留区域执行异常指令时,可以将待写入的数据写入第二保留区域,保证用户程序正常执行,因此能够使得用户程序模拟执行访问重定向空间的指令。
一种可能的实现方法中,所述信号处理函数将修改后的所述异常指令写入第一保留区域。
一种可能的实现方法中,在上述步骤105中,所述信号处理函数获取所述第一模拟结果之后,还包括:所述信号处理函数解析所述异常指令,判断所述异常指令是否包括写操作;若异常指令包括写操作,且待写入数据对应的内存地址位于所述内核空间,所述信号处理函数从所述第二保留区域获取所述待写入数据;所述信号处理函数向所述内核发送第四请求;所述第四请求,用于请求所述内核写入数据到重定向空间,所述重定向空间指的是与所述内核空间存在映射关系的地址空间。具体地,所述重定向空间指的是一段可位于也可不位于内存上的地址空间,它与所述内核空间上的地址之间存在一定的映射关系;通过所述映射关系,所述异常指令的访存地址可被映射到重定向地址。
也就是说,在得到第一模拟结果之后,判断是否需要将第一模拟结果对应的待写入数据写入重定向空间,如果需要写入,则信号处理函数向内核发送第四请求,请求内核写入数据到重定向空间。该方案,能够实现准确有效地处理访存地址位于内核空间的写操作到重定向空间,能够使得用户程序模拟执行访问内核空间的指令。
一种可能的实现方法中,请求内核写入数据到重定向空间之后,所述信号处理函数修改所述第三上下文,确定第四上下文;所述信号处理函数向所述内核发送第五请求;所述第五请求,用于请求内核使用所述第四上下文恢复程序执行。
下面对第一保留区域和第二保留区域进行解释。
一种可能的实现方法中,在所述用户程序启动时,设置第一保留区域和第二保留区域;或,在首次为所述用户程序分配内核空间时,设置第一保留区域和第二保留区域。第一保留区域和第二保留区域,可以由运行时库或用户程序的内存分配包装器分配完成,第一保留区域和第二保留区域和一个普通的用户空间内存分配没有实质性区别,只要这两个区域不被释放,就相当于将其保留下来了,唯一的要求就是,在执行所述异常指令之前,这两个区域存在且至少能满足模拟一条异常指令所需的内存大小和权限。该方案,能够提高分配第一保留区域和第二保留区域的灵活性。
一种可能的实现方法中,从用户程序启动至用户程序退出期间,第一保留区域和第二保留区域可以动态设置,也就是说,完全可以按照需求将这两个区域动态扩增或缩小(并可能伴随着位置的移动),或者不改变大小而只是移动位置。
第一保留区域,用于在实施模拟执行异常指令时,暂存被执行模拟的指令,这些指令在这个区域被执行。设置这个区域是因为:1)重定向空间无法被直接访问,用户程序也无权访问真正的内核空间,因此本身位于重定向空间中的指令要被拷贝到此处才能执行;2)无论被执行模拟的指令位于用户空间还是非用户空间,都需要在执行完所需模拟的指令后立即返回,因而需要一个特殊的区域用于在所需模拟的指令之后放置用于返回signalhandler的指令。这些被暂存到此处的将要被执行模拟的指令,可以是原本的指令的一个未修改的拷贝,也可能在所述前处理阶段发生过修改(如,对于使用立即数的访存指令,如果要访问内核空间,需要修改立即数,使得访存地址指向第一保留区域)。该区域的大小,决定了合并模拟时最大可一次性模拟的指令条数。举例如下:如果第一保留区域的大小,除去用于放置用于返回signal handler的指令所必须占用的空间后,是4092Byte,那么最多可以在合并模拟时一次性模拟1023条指令长度为4Byte的指令(大多数RISC架构都使用4Byte的定长指令)。对于变长指令集(典型的,如x86),由于每条指令的指令长度不一致,则无法准确预测合并模拟时最大可一次性模拟的指令条数。
由于第一保留区域在用户空间,且由于执行模拟的关键就是在第一保留区域完成执行,因此,在进入第一保留区域执行前,该区域对应的页面必须具备可执行权限;而,将指令拷贝(写入)到这一区域需要写权限。要达成这一目的,需要通过系统调用请求内核修改页面权限(如mprotect()系统调用可用于修改已分配页面的权限,或在请求内核分配内存如mmap()时就带上页面权限的参数)。举例来说,这可以通过三种方式来实现:
1. 在分配它的时候或分配之后立即将其设为不可读可写可执行。这样随后就不再需要改变它的权限了。这样方便,所需的系统调用次数少,性能高。当然,对于一些架构要求可执行必定可读,或者,可写必定可读等,在分配它的时候或分配之后立即将其设为可写可执行,本申请对这些架构依然使用,后续不再赘述。
2. 在分配它的时候或分配之后立即将其设为不可读不可写不可执行。然后在每次需要使用第一保留区域之前,先将其设置为可写,再将对应指令写入其中,然后将其设置为不可读不可写(以防被模拟执行的指令错误地读写到本区域)可执行;在第一保留区域中的指令执行完成之后,又将其恢复为不可读不可写不可执行。这样的安全性高,能够立刻发现任何内存误用。
3. 在分配它的时候或分配之后立即将其设为不可读可写不可执行,然后在将对应指令写入第一保留区域后,将其设置为不可读不可写可执行。在第一保留区域中的指令执行完成之后,又其恢复为不可读可写不可执行。这与第2中方式类似,但减少一次页面权限设置,性能得到提升。
一种可能的实现方法中,在第一保留区域放入被执行模拟的指令后,还要紧随其后放入用于立即跳转回signal handler的指令。这样的指令,本身不应该改变除了PC之外的任何上下文(如:不能改变寄存器中的值等),举例如:立即数跳转指令、无条件自陷(trap)指令等。立即数跳转指令将在无需内核协助的情况下,跳转回signal handler,此时,signal handler需要自行进行上下文的保存以供后续使用。无条件自陷指令将引发陷阱,从而陷入内核态,内核会由此产生信号(如SIGTRAP),只要针对对应信号也注册signalhandler,则可以在signal handler中取得内核传递来的上下文,signal handler就不需要自行进行上下文的保存了。前者性能较高,但是实现复杂;后者实现简单,但是开销较大(因为涉及到用户态和内核态的切换)。
第二保留区域,在实施模拟执行异常指令时,暂存被模拟的指令所需访问到的位于内核空间中的地址上的数据,设置这个区域是因为内核空间无法被直接访问,因此使用此区域作为一个数据的中转站。通过实施模拟执行异常指令之前修改上下文,能够将需要访问内核空间的指令的访存地址改为第二保留区域中的地址,从而实现指令的正确访存和执行。该区域的大小,决定了合并模拟时最大可一次性模拟的指令条数。举例如下:如果第二保留区域的大小是4096Byte,那么最多可以在合并模拟时一次性模拟4096条在不同地址上读写1个Byte的指令,或一次性模拟1024条在不同地址上读写4个Byte的指令,或无限制地模拟不访问内存的指令。需要注意的是,这里需要特别强调「不同地址」是因为:如果数条指令访问的是同一个地址,则它们在第二保留区域内占用的是同一个位置,因此访问同一地址的指令的数目可以是无限制的(只要第二保留区域没有被其它指令完全占用至无空间剩下)。
由于第二保留区域在用户空间,且由于执行模拟可能需要对其进行读写。因此,如果执行模拟需要用到第二保留区域,则在进入第二保留区域执行前,第二保留区域对应的页面必须具备可读和/或可写权限。要达成这一目的,需要通过系统调用请求内核修改页面权限(如mprotect()系统调用可用于修改已分配页面的权限,或在请求内核分配内存如mmap()时就带上页面权限的参数)。举例来说,这可以通过两种方式来实现:
1. 在分配它的时候或分配之后立即将其设为可读可写不可执行,这样随后就不再需要改变它的权限了。这样方便,所需的系统调用次数少,性能高。用户程序如果由于错误或者疏忽跳转到第二保留区域执行时,此时第二保留区域的权限为不可执行,可以辨识这是一个内存误用。
2. 在分配它的时候或分配之后立即将其设为不可读不可写不可执行,然后在每次需要使用第二保留区域之前,先将其设置为可读可写不可执行,再将模拟执行所需的数据写入第二保留区域,然后就可以进入第一保留区域完成指令的执行。在后续,如有需要从第二保留区域取得所需数据后,又将其恢复为不可读不可写不可执行。这样的安全性高,能够立刻发现用户程序对第二保留区域的任何内存误用。
一种可能的实现方法中,所述信号处理函数获取所述用户程序中位于所述异常指令后的N条指令;N为大于等于0的整数;所述信号处理函数将所述异常指令及所述N条指令写入所述第一保留区域;所述信号处理函数将所述第一跳转指令写入第一保留区域;所述第一跳转指令位于所述异常指令和所述N条指令之后。其中,N条指令不一定是异常指令,也可以为正常指令。对于此方法,本申请将其称为“合并模拟”。该方案,能够实现一次性地模拟执行异常指令及N条指令,提高程序执行效率,减少不必要的上下文切换和信号处理,提升性能。
合并模拟,可以一次性将多条指令写入第一保留区域,然后在第一保留区域一次性执行完多条指令,得到模拟结果。该方法能够大幅节省来回跳转的开销,节省一些不必要的中间状态处理。不过,合并模拟最大可一次性模拟的指令条数,取决于指令类型、第一保留区域和第二保留区域的大小。举例如下:假设第二保留区域的大小位为2048Byte,第一保留区域除去用于放置用于返回signal handler的指令所必须占用的空间后为4092Byte。假设所有指令都是定长的,指令长度为4Byte。如果已经有512条在不同地址上读写4个Byte的指令,则第二保留区域被全部用完,但第一保留区域还有2044Byte可用;此时,不可以增加访存地址不与第二保留区域已经存在的任意一条指令的访存地址相同的指令了,但是可以继续增加不访存的指令或者访存地址与已经存在的任意一条指令的访存地址相同的指令,直至第一保留区域也被用完。如果已经有1023条在不同地址上读写1个Byte的指令,则第一保留区域被全部用完,此时第二保留区域还有1024Byte可用,但也不可能再增加指令了。如果已经有1023条非访存指令,则第一保留区域被全部用完,此时第二保留区域虽然没有被使用,但也不可能再增加指令了。
一种可能的实现方法中,所述信号处理函数获取所述异常指令的下一条指令并将所述下一条指令作为异常指令;继续执行将所述异常指令和第一跳转指令写入第一保留区域,直至完成M条指令,M为大于等于1的整数。其中,M条指令不一定是异常指令,也可以为正常指令。对于此方法,本申请将其称为“连续模拟”。
连续模拟指的是,在模拟完成一条异常指令后,不一定就回到正常执行,而是可以继续取出一条指令并模拟执行。
对于被模拟执行的异常指令,如果异常指令本身位于内核空间,基于除了跳转(分支)指令外,绝大部分指令都是顺序执行的,则单条异常指令被模拟后,下一条将要执行的指令极有可能也位于内核空间,因此,下一条将要执行的指令极有可能也需要被模拟。因此,可以在模拟完成一条指令后,不回到正常执行,而继续取这条指令的下一条指令(如果是跳转指令,则是跳转目标处的指令)继续模拟执行。每次模拟的指令数量可以是没有限制的,完全可以如此往复直到遇到不再必须被模拟执行的指令。这和trap-and-emulate不同,trap-and-emulate由于运行在内核态,每次运行,不可以无限制地进行指令模拟,否则长时间停留在内核态会使系统停顿。而本申请中,signal handler 位于用户态,其可无限制地继续模拟而不需担心造成系统整体的停顿。
对于被模拟执行的异常指令,如果被模拟的指令是一条访问了内核空间的访存指令,基于这样一个事实:每次访存,往往并不只是访问单个地址,而是多个地址(常常也是相邻的)都被访问。比如,取出几个地址上的数据到寄存器里,运算后,又放回这几个地址。可见,访存指令常常是成簇出现的,且由于成簇出现的访存指令所访问的地址很可能也相邻,则如果这簇访存指令有一条要被模拟,剩余的也很可能都必须被模拟。
连续模拟,可以减少在返回用户程序正常执行后又立即触发由于访问内核空间导致异常出现的情况,进而减少不必要的上下文切换和信号处理,提升性能。
图2为本申请实施例提供的一种异常指令的处理方法,该方法为上述步骤101至步骤105的具体实现过程,该方法包括以下步骤:
步骤201,信号处理函数获取用户程序在运行到异常指令时所对应的第一上下文。
步骤202,信号处理函数从第一上下文中取出异常指令。
步骤203,信号处理函数解析异常指令,判断异常指令是否包括读操作。
一种可能的实现方法中,若异常指令不包括读操作,则将所述异常指令写入第一保留区域,即执行步骤208;异常指令包括读操作,则执行步骤204。
步骤204,信号处理函数判断读操作对应的访存地址是否位于内核空间。
一种可能的实现方法中,若读操作对应的访存地址不位于内核空间,则将所述异常指令写入第一保留区域,即执行步骤208;若读操作对应的访存地址位于内核空间,则执行步骤205。
步骤205,信号处理函数向内核发送第三请求。
一种可能的实现方法中,信号处理函数向内核发送第三请求,请求内核读取位于内核空间的数据;内核将数据从内核空间读出后,返回给信号处理函数。
步骤206,信号处理函数获取内核发送的数据,并将该数据写入第二保留区域。
步骤207,信号处理函数修改异常指令和/或第一上下文。
一种可能的实现方法中,若访存地址由立即数确定,则修改该异常指令,使得该指令需要访问的地址位于第二保留区域;若该访存地址由寄存器确定,则修改第一上下文,也即修改寄存器对应的数据,使得寄存器存储的数据与第二保留区域对应的地址有关。
步骤208,信号处理函数将异常指令和第一跳转指令写入第一保留区域。
一种可能的实现方法中,若上述步骤修改了异常指令和/或第一上下文,则将修改后的异常指令写入第一保留区;再将第一跳转指令写入第一保留区域;若上述步骤未修改异常指令和第一上下文,则将原始异常指令写入第一保留区;再将第一跳转指令写入第一保留区域。
步骤209,信号处理函数修改第一上下文,确定第二上下文。
其中,第二上下文中的程序计数器指向第一保留区域的地址。
步骤210,信号处理函数请求内核使用第二上下文恢复程序执行。
一种可能的实现方法中,图3示例性地示出了内核接收到信号处理函数发送的使用第二上下文恢复程序执行请求后的执行步骤,该步骤包括以下内容:
步骤301,内核使用第二上下文恢复程序执行。
步骤302,用户程序在第一保留区域执行异常指令,得到模拟结果。
步骤303,由于异常指令执行的效应,上下文发生了改变,记为第三上下文。
步骤304,执行第一跳转指令,跳转到信号处理函数。
一种可能的实现方法中,若第一跳转指令为立即数跳转指令,则直接跳转至信号处理函数,并由信号处理函数保留第三上下文。
一种可能的实现方法中,通过信号处理返回信号处理函数,比如可以通过无条件自陷指令跳转至信号处理函数,当然也可以通过其它指令跳转至信号处理函数,本申请对此不做限定。
一种可能的实现方法中,通过该无条件自陷指令跳转至信号处理函数的具体过程如下:执行无条件自陷指令触发异常,内核接收到异常信号后,保留用户程序在引发异常时的上下文即第三上下文;判断异常类型,若确定该异常是由于无条件自陷指令引发的陷阱(SIGTRAP),则将第三上下文传递给SIGTRAP对应的signal handler,信号处理函数从传入的参数中,取得第三上下文。
一种可能的实现方法中,在用户程序执行之前,或为用户程序分配内核空间时,注册SIGTRAP对应的signal handler,以覆盖SIGTRAP的默认处理方式。
步骤305,信号处理函数从第三上下文中获取模拟结果。
一种可能的实现方法中,图4示例性地示出了信号处理函数在获取模拟结果之后的步骤,如下所示:
步骤401,信号处理函数解析异常指令,判断异常指令是否包括写操作。
一种可能的实现方法中,若异常指令不包括写操作,则执行步骤405;若异常指令包括写操作,则执行步骤402。
步骤402,信号处理函数判断是否要写入数据到内核空间。
一种可能的实现方法中,若异常指令无需写入数据到内核空间,则执行步骤405;若需要写入数据到内核空间,则执行步骤403。
步骤403,信号处理函数从第二保留区域获取该异常指令被执行后写入的数据。
步骤404,信号处理函数向内核发送第四请求,请求内核写入数据到重定向空间。
步骤405,信号处理函数修改第三上下文,确定第四上下文。
其中,第四上下文中的程序计数器指向异常指令的下一条指令。
一种可能的实现方法中,由于在前述图1的步骤中可能对第一上下文进行了修改以改变异常指令的访存地址,则此时的第三上下文中可能传承了此等修改;为了使这些修改不要影响到程序后续的正常执行,则在第四上下文中回滚这些修改。
步骤406,信号处理函数请求内核根据第四上下文恢复程序执行。
一种可能的实现方法中,在获取模拟结果之后,将待模拟结果写入到重定向空间。
下面以几个具体的例子,来解释说明如何处理异常指令。
(1) 如异常指令为 ADDU $1, $2, $3,这条指令用伪代码表示就是$1=$2+$3。则不需要用到第二保留区域,异常指令和寄存器数据也都不需要被修改。在将该指令写入到用户空间中的第一保留区域后,修改上下文A(对应于所述第一上下文)得到上下文A1(对应于所述第二上下文),其中PC被修改为第一保留区域的起始地址;使用上下文A1恢复程序执行(相当于跳转到第一保留区域执行);该指令执行后,基于该指令执行的效应,上下文A1已经发生改变,记为A2(对应于所述第三上下文);由于第一保留区域包括第一跳转指令,该第一跳转指令执行后就会立刻回到signal handler,signal handler由此可提取上下文A2,修改上下文A2得到上下文D(对应于所述第四上下文),其中PC被修改为所述指令的下一条指令。
(2) 如异常指令为LW $1, 8($2),这条指令表示:从寄存器$2中取出地址y,将其加上8得到y+8,并从地址y+8处读取一个字(word,32位bit,或4字节byte)z,并将z写入寄存器$1。则从上下文A中取出寄存器$2的值y,再从地址y+8处读取一个字z。如果地址y+8在内核空间,使用模拟访存读取到z,将z写入到第二保留区域(地址为m),并将修改上下文A(对应于所述第一上下文)得到A1,其中$2的值被修改为m-8;如果不在,则不需要用到第二保留区域也暂时不需要修改上下文。在将该指令写入到用户空间中的第一保留区域后,将上下文A1(如果地址y+8在内核空间)或A(如果地址y+8不在内核空间)进一步修改,仍记作A1(对应于所述第二上下文),其中PC被修改为第一保留区域的起始地址;使用上下文A1恢复程序执行(相当于跳转到第一保留区域执行);该指令执行后,基于该指令执行的效应,上下文A1已经发生改变,记为A2(对应于所述第三上下文);由于第一保留区域包括第一跳转指令,该第一跳转指令执行后就会立刻回到signal handler,signal handler由此可提取上下文A2,修改上下文A2得到上下文D(对应于所述第四上下文),其中$2的值被重新改回y,PC被修改为所述指令的下一条指令。
(3) 如异常指令为SB $1, -16($2),这条指令表示:从寄存器$2中取出地址u,将其减去16得到u-16,其中,u-16位于内核空间,并将寄存器$1中的值v截取到一个字节(byte,8bit)后写入地址u-16。则从上下文A(对应于所述第一上下文)中取出寄存器$1的值v和寄存器$2的值u。假设第二保留区域的地址为m。如果地址u-16在内核空间,并将修改上下文A得到A1,其中$2的值被修改为m+16;如果不在,则不需要用到第二保留区域也暂时不需要修改上下文。在将该指令写入到用户空间中的第一保留区域后,将上下文A1(如果地址u-16在内核空间)或A(如果地址u-16不在内核空间)进一步修改,仍记作A1(对应于所述第二上下文),其中PC被修改为第一保留区域的起始地址;使用上下文A1恢复程序执行(相当于跳转到第一保留区域执行);该指令执行后,基于该指令执行的效应,上下文A1已经发生改变,记为A2(对应于所述第三上下文);由于第一保留区域包括第一跳转指令,该第一跳转指令执行后就会立刻回到signal handler,signal handler由此可提取上下文A2,修改上下文A2得到上下文D(对应于所述第四上下文),其中$2的值被重新改回u,PC被修改为所述指令的下一条指令。且,如果地址u-16在内核空间,将地址m处的一个字节读出后,使用模拟访存写入地址u-16。
一种可能的实现方法中,所述信号处理函数将所述异常指令和第一跳转指令写入第一保留区域之前,还包括:确定所述异常指令为复杂指令;所述复杂指令中包括访存操作及运算操作、多次访存操作或多次运算操作。
对于RISC(精简指令集计算机)架构, RISC架构的访存指令永远只负责单向(即,一条访存指令,要么只完成内存读取,要么只完成内存写入,而不能两者一次性完成)的访存,且不带有对访存的目标数据(读取到的数据或将写入的数据)的运算操作。
对于CISC(复杂指令集计算机)架构的指令,它可以在一条指令里就完成对某个内存地址上的数据的运算(也就相当于,在一条指令内全部完成这三步:读出该地址上的数据、执行对应运算、将运算结果写入该地址)。也就是说,CISC架构的指令相对于RISC架构的指令更复杂。
也就是说,上述异常指令的处理方法更适用于CISC(复杂指令集计算机)架构的指令,而对于RISC(精简指令集计算机)架构的指令,本申请提供了另一种实施方式,该方式能够提高模拟执行的效率。当然该方法虽然更加适用RISC(精简指令集计算机)架构的指令,但也可以用于CISC(复杂指令集计算机)架构的指令,本申请对此不做限定。
该实施方式如图5所示,包括以下步骤:
步骤501,信号处理函数确定异常指令为访存指令。
步骤502,信号处理函数解析异常指令,确定异常指令的访存地址位于内核空间。
步骤503,信号处理函数确定访存地址对应的第一重定向地址。
其中,所述第一重定向地址是指重定向空间中的某个地址。
步骤504,信号处理函数向内核发送第二请求。
其中,第二请求用于请求内核根据第一重定向地址进行数据读写操作。
步骤505,信号处理函数获取内核的读写结果,模拟执行异常指令,得到第二模拟结果。
一种可能的实现方法中,若上述访存指令为从内核空间读取数据,该方法包括以下步骤,如图6所示。
步骤601,信号处理函数确定异常指令为访存指令。
步骤602,信号处理函数判断该访存指令是否需要从内核空间读取数据。
一种可能的实现方法中,该访存指令不需要从内核空间读取数据,即该访存指令可能需要从用户空间或者寄存器中读取数据,即执行步骤606。
一种可能的实现方法中,该访存指令需要从内核空间读取数据,则执行步骤603。
步骤603,信号处理函数确定访存地址对应的第一重定向地址。
一种可能的实现方法中,该访存指令需要从内核空间读取数据,则根据访存指令对应的虚拟地址,映射得到对应的重定向地址;然后通过系统调用请求内核读取第一重定向地址对应的数据。
步骤604,信号处理函数向内核发送第二请求,请求内核读取第一重定向地址对应的数据。
步骤605,内核将第一重定向地址对应的数据发送给信号处理函数。
步骤606,信号处理函数从用户空间和/寄存器读取对应的数据。
一种可能的实现方法中,如果该访存指令要读取用户空间的数据,从该访存指令所需读取的用户空间地址上读取对应的数据;如果该访存指令要读取寄存器中的数据,从第一上下文中读取该访存指令所需读取的寄存器对应的数据。
一种可能的实现方法中,该访存指令可能既需要从内核空间读取数据,又需要从用户空间和/寄存器读取对应的数据,因此在步骤602确定需要从内核空间读取数据后,还可以执行步骤606。
一种可能的实现方法中,该访存指令可能不需要从用户空间和/或寄存器读取数据,则步骤606不需要发生实际的读取。
步骤607,信号处理函数根据读取的数据,结合访存指令的行为,直接模拟执行该访存指令,得到第二模拟结果。
一种可能的实现方法中,信号处理函数修改第一上下文,修改PC使其指向该异常指令的下一条指令或跳转指令的跳转目标,并向内核发送请求,使内核根据修改后的第一上下文恢复程序执行。
一种可能的实现方法中,若上述访存指令需要向内核空间写入数据,该方法包括以下步骤,如图7示。
步骤701,信号处理函数确定异常指令为访存指令。
步骤702,信号处理函数判断该访存指令是否需要向内核空间写入数据。
一种可能的实现方法中,该访存指令不需要向内核空间写入数据,即该访存指令可能需要向用户空间或寄存器中写入数据,即执行步骤705。
一种可能的实现方法中,该访存指令需要向内核空间写入数据,则执行步骤703。
步骤703,信号处理函数确定访存地址对应的第一重定向地址。
一种可能的实现方法中,该访存指令需要向内核空间写入数据,则根据访存指令对应的虚拟地址,映射得到对应的重定向地址;然后通过系统调用请求内核向第一重定向地址写入数据。
步骤704,信号处理函数向内核发送第二请求,请求内核向第一重定向地址写入数据。
步骤705,信号处理函数向用户空间和/或寄存器写入对应的数据。
一种可能的实现方法中,如果该访存指令需要向用户空间写入数据,则将对应的数据写入用户空间;如果该访存指令需要向寄存器写入数据,则修改第一上下文中目标寄存器对应的数据。
一种可能的实现方法中,将第二模拟结果写入内核空间或用户空间或寄存器。
一种可能的实现方法中,该访存指令可能不需要写入数据到用户空间和/或寄存器,则步骤705不需要发生实际的写入。
步骤706,信号处理函数修改第一上下文。
一种可能的实现方法中,信号处理函数修改第一上下文,修改PC使其指向该异常指令的下一条指令或跳转指令的跳转目标,并向内核发送请求,使内核根据修改后的第一上下文恢复程序执行。
上述方案,若异常指令为访存指令时,可以不把异常指令写入第一保留区域,而由内核对数据进行读写操作后,再由信号处理函数直接模拟执行所述异常指令。该方案,能够有效地处理访存指令,提高用户程序执行效率。
下面以几个具体的例子,来解释说明如何根据步骤501至步骤505处理异常指令。
(1) 如异常指令为 ADDU $1, $2, $3,这条指令用伪代码表示就是$1=$2+$3,则模拟执行异常指令,得到模拟结果为:从上下文A(对应于所述第一上下文)中取出寄存器$2和$3的值,相加后得到值x;修改上下文A得到上下文D(对应于所述修改后的第一上下文),其中$1被修改为x、PC被修改为所述指令的下一条指令。
(2) 如异常指令为LW $1, 8($2),这条指令表示:从寄存器$2中取出地址y,将其加上8得到y+8,并从地址y+8处读取一个字(word,32位bit,或4字节byte)z,并将z写入寄存器$1,则模拟执行异常指令,得到模拟结果为:从上下文A(对应于所述第一上下文)中取出寄存器$2的值y,再从地址y+8处读取一个字z(如果地址y+8在内核空间,则请求内核模拟访存;如果不在,则正常访存);修改上下文A得到上下文D(对应于所述修改后的第一上下文),其中$1被修改为z、PC被修改为所述异常指令的下一条指令。
(3) 如异常指令为SB $1, -16($2),这条指令表示:从寄存器$2中取出地址u,将其减去16得到u-16,其中,u-16位于内核空间,并将寄存器$1中的值v截取到一个字节(byte,8bit)后写入地址u-16,则模拟执行异常指令,得到模拟结果为:从上下文A(对应于所述第一上下文)中取出寄存器$1的值v和寄存器$2的值u;修改上下文A得到上下文D(对应于所述修改后的第一上下文),其中PC被修改为所述异常指令的下一条指令,且,将v截取到一个字节后请求内核模拟访存写入地址u-16。
(4) 如异常指令为JR $31,这条指令表示,从寄存器$31中取出地址w,并跳转到地址w处继续执行,则模拟执行异常指令,得到模拟结果为:从上下文A(对应于所述第一上下文)中取出寄存器$31的值w;修改上下文A得到上下文D(对应于所述修改后的第一上下文),其中PC被修改为w。
基于相同的技术构思,图8示例性地示出了本申请实施例提供的一种异常指令的处理装置800,包括:获取单元801和处理单元802。所述获取单元801,用于获取用户程序在运行到异常指令时所对应的第一上下文;所述信号处理函数是所述用户程序注册的,用于替换内核对所述异常指令的默认处理方式;所述处理单元802,用于将所述异常指令和第一跳转指令写入第一保留区域;所述异常指令是基于所述第一上下文获取的;所述第一保留区域位于用户空间,用于暂存以及执行被模拟的指令;所述第一跳转指令,位于所述异常指令之后,用于指示跳转回所述信号处理函数; 所述信号处理函数修改所述第一上下文,确定第二上下文;其中,所述第二上下文中的程序计数器指向所述第一保留区域的地址;所述信号处理函数向所述内核发送第一请求;所述第一请求用于请求所述内核使用所述第二上下文恢复程序执行;在所述第一保留区域执行完所述异常指令并得到第一模拟结果后,根据所述第一跳转指令返回所述信号处理函数,所述信号处理函数获取所述第一模拟结果。
一种可能的实现方法中,所述处理单元802,用于接收所述用户程序触发的页面异常,并确定所述页面异常的类型为段错误;所述内核触发所述信号处理函数,并将发生页面异常时的第一上下文作为参数发送给所述信号处理函数;所述信号处理函数从所述第一上下文中获取引发页面异常的访存地址,并确定所述访存地址位于内核空间。
一种可能的实现方法中,所述处理单元802,用于解析所述异常指令,判断所述异常指令是否包括读操作;若所述异常指令包括读操作,且所述读操作对应的访存地址位于内核空间,则所述信号处理函数向内核发送第三请求;所述第三请求用于请求所述内核读数据;所述信号处理函数将所述数据写入第二保留区域;所述第二保留区域位于用户空间,所述第二保留区域用于暂存被模拟的指令所需访问的数据;所述信号处理函数根据所述数据在所述第二保留区域对应的地址,修改所述异常指令和/或所述第一上下文;所述信号处理函数将所述异常指令写入第一保留区域,包括:所述信号处理函数将修改后的所述异常指令写入第一保留区域。
一种可能的实现方法中,所述处理单元802,用于解析所述异常指令,判断所述异常指令是否包括写操作;若异常指令包括写操作,且所述写操作对应的访存地址位于内核空间,所述信号处理函数在所述第二保留区域预设一个地址用于所述写操作,并根据预设的地址修改所述异常指令和/或所述第一上下文。
一种可能的实现方法中,所述处理单元802,用于解析所述异常指令,判断所述异常指令是否包括写操作;若异常指令包括写操作,且待写入数据对应的内存地址位于所述内核空间,所述信号处理函数从所述第二保留区域获取所述待写入数据;所述信号处理函数向所述内核发送第四请求;所述第四请求,用于请求所述内核将所述待写入的数据写入重定向空间;所述重定向空间指的是与所述内核空间存在映射关系的地址空间。
一种可能的实现方法中,所述处理单元802,用于获得第三上下文,所述第三上下文是在所述第一保留区域执行所述异常指令产生的;所述信号处理函数从所述第三上下文中获取所述第一模拟结果。
一种可能的实现方法中,所述处理单元802,用于修改所述第三上下文,确定第四上下文;其中,所述第四上下文中的程序计数器指向所述异常指令的下一条指令;所述信号处理函数向所述内核发送第五请求;所述第五请求,用于请求内核使用所述第四上下文恢复程序执行。
一种可能的实现方法中,所述处理单元802,用于获取所述用户程序中位于所述异常指令后的N条指令;N为大于等于0的整数;所述信号处理函数将所述异常指令及所述N条指令写入所述第一保留区域;所述信号处理函数将所述第一跳转指令写入第一保留区域;所述第一跳转指令位于所述异常指令和所述N条指令之后。
一种可能的实现方法中,所述处理单元802,用于确定所述异常指令为复杂指令;所述复杂指令中包括访存操作及运算操作、多次访存操作或多次运算操作。
一种可能的实现方法中,所述处理单元802,用于确定所述异常指令为访存指令;所述信号处理函数解析所述异常指令,确定所述异常指令的访存地址位于内核空间;所述信号处理函数确定所述访存地址对应的第一重定向地址;所述第一重定向地址是位于重定向空间的地址;所述信号处理函数向所述内核发送第二请求;所述第二请求用于请求所述内核根据所述第一重定向地址进行数据读写操作;所述信号处理函数获取所述内核的读写结果,模拟执行所述异常指令,得到第二模拟结果。
一种可能的实现方法中,所述处理单元802,用于在所述用户程序启动时,设置第一保留区域和第二保留区域;或,
在首次为所述用户程序分配内核空间时,设置第一保留区域和第二保留区域。
一种可能的实现方法中,所述处理单元802,用于分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置不可读不可写不可执行;向所述第一保留区域写入异常指令时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置不可读不可写不可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置可写不可执行。
一种可能的实现方法中,所述处理单元802,用于分配所述第二保留区域时,将所述第二保留区域对应的权限设置可读可写不可执行;或,
分配所述第二保留区域时,将所述第二保留区域对应的权限设置不可读不可写不可执行;对所述第二保留区域进行读操作或写操作时,将所述第二保留区域对应的权限设置可读可写不可执行;完成对所述第二保留区域读操作或写操作时,将所述第二保留区域对应的权限设置不可读不可写不可执行。
基于相同的技术构思,本申请实施例提供了一种异常指令的处理装置900,该一种异常指令的处理装置900比如可以是一个计算设备。如图9所示,一种异常指令的处理装置900包括至少一个处理器901,以及与至少一个处理器连接的存储器902,本申请实施例中不限定处理器901与存储器902之间的具体连接介质,图9中处理器901和存储器902之间通过总线连接为例。总线可以分为地址总线、数据总线、控制总线等。
在本申请实施例中,存储器902存储有可被至少一个处理器901执行的指令,至少一个处理器901通过执行存储器902存储的指令,可以执行上述一种异常指令的处理方法。
其中,处理器901是一种异常指令的处理装置900的控制中心,可以利用各种接口和线路连接计算机设备的各个部分,通过运行或执行存储在存储器902内的指令以及调用存储在存储器902内的数据,从而进行资源设置。可选地,处理器901可包括一个或多个确定单元,处理器901可集成应用处理器和调制解调处理器,其中,应用处理器主要处理操作系统、用户界面和应用程序等,调制解调处理器主要处理无线通信。可以理解的是,上述调制解调处理器也可以不集成到处理器901中。在一些实施例中,处理器901和存储器902可以在同一芯片上实现,在一些实施例中,它们也可以在独立的芯片上分别实现。
处理器901可以是通用处理器,例如中央处理器(CPU)、数字信号处理器、专用集成电路(Application Specific Integrated Circuit,ASIC)、现场可编程门阵列或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件,可以实现或者执行本申请实施例中公开的各方法、步骤及逻辑框图。通用处理器可以是微处理器或者任何常规的处理器等。结合本申请实施例所公开的方法的步骤可以直接体现为硬件处理器执行完成,或者用处理器中的硬件及软件模块组合执行完成。
存储器902作为一种非易失性计算机可读存储介质,可用于存储非易失性软件程序、非易失性计算机可执行程序以及模块。存储器902可以包括至少一种类型的存储介质,例如可以包括闪存、硬盘、多媒体卡、卡型存储器、随机访问存储器(Random AccessMemory,RAM)、静态随机访问存储器(Static Random Access Memory,SRAM)、可编程只读存储器(Programmable Read Only Memory,PROM)、只读存储器(Read Only Memory,ROM)、带电可擦除可编程只读存储器(Electrically Erasable Programmable Read-Only Memory,EEPROM)、磁性存储器、磁盘、光盘等等。存储器902是能够用于携带或存储具有指令或数据结构形式的期望的程序代码并能够由计算机存取的任何其他介质,但不限于此。本申请实施例中的存储器902还可以是电路或者其它任意能够实现存储功能的装置,用于存储程序指令和/或数据。
本申请实施例还提供一种计算机可读存储介质,计算机可读存储介质存储有计算机可执行程序,计算机可执行程序用于使计算机执行上述任一方式所列的一种异常指令的处理方法。
本申请实施例提供了一种计算机程序产品,包括有可由计算机设备执行的计算机程序,当所述程序在计算机设备上运行时,使得所述计算机设备执行上述任一方式所列的一种异常指令的处理方法。
本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本申请是参照根据本申请的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
显然,本领域的技术人员可以对本申请进行各种改动和变型而不脱离本申请的精神和范围。这样,倘若本申请的这些修改和变型属于本申请权利要求及其等同技术的范围之内,则本申请也意图包含这些改动和变型在内。
Claims (16)
1.一种异常指令的处理方法,其特征在于,包括:
信号处理函数获取用户程序在运行到异常指令时所对应的第一上下文;所述信号处理函数是所述用户程序注册的,用于替换内核对所述异常指令的默认处理方式;
所述信号处理函数将所述异常指令和第一跳转指令写入第一保留区域;所述异常指令是基于所述第一上下文获取的;所述第一保留区域位于用户空间,用于暂存以及执行被模拟的指令;所述第一跳转指令,位于所述异常指令之后,用于指示跳转回所述信号处理函数;
所述信号处理函数修改所述第一上下文,确定第二上下文;其中,所述第二上下文中的程序计数器指向所述第一保留区域的地址;
所述信号处理函数向所述内核发送第一请求;所述第一请求用于请求所述内核使用所述第二上下文恢复程序执行;
在所述第一保留区域执行完所述异常指令并得到第一模拟结果后,根据所述第一跳转指令返回所述信号处理函数,所述信号处理函数获取所述第一模拟结果。
2.如权利要求1所述的方法,其特征在于,所述信号处理函数获取用户程序在运行到异常指令时所对应的第一上下文之前,还包括:
所述内核接收所述用户程序触发的页面异常,并确定所述页面异常的类型为段错误;
所述内核触发所述信号处理函数,并将发生页面异常时的第一上下文作为参数发送给所述信号处理函数;
所述信号处理函数从所述第一上下文中获取引发页面异常的访存地址,并确定所述访存地址位于内核空间。
3.如权利要求1所述的方法,其特征在于,所述信号处理函数将所述异常指令和第一跳转指令写入第一保留区域之前,还包括:
所述信号处理函数解析所述异常指令,判断所述异常指令是否包括读操作;
若所述异常指令包括读操作,且所述读操作对应的访存地址位于内核空间,则所述信号处理函数向内核发送第三请求;所述第三请求用于请求所述内核读数据;
所述信号处理函数将所述数据写入第二保留区域;所述第二保留区域位于用户空间,所述第二保留区域用于暂存被模拟的指令所需访问的数据;
所述信号处理函数根据所述数据在所述第二保留区域对应的地址,修改所述异常指令和/或所述第一上下文;
所述信号处理函数将所述异常指令写入第一保留区域,包括:
所述信号处理函数将修改后的所述异常指令写入第一保留区域。
4.如权利要求1所述的方法,其特征在于,所述信号处理函数将所述异常指令和第一跳转指令写入第一保留区域之前,还包括:
所述信号处理函数解析所述异常指令,判断所述异常指令是否包括写操作;
若异常指令包括写操作,且所述写操作对应的访存地址位于内核空间,所述信号处理函数在所述第二保留区域预设一个地址用于所述写操作,并根据预设的地址修改所述异常指令和/或所述第一上下文;
所述信号处理函数将所述异常指令写入第一保留区域,包括:
所述信号处理函数将修改后的所述异常指令写入第一保留区域。
5.如权利要求1所述的方法,其特征在于,所述信号处理函数获取所述第一模拟结果之后,还包括:
所述信号处理函数解析所述异常指令,判断所述异常指令是否包括写操作;
若所述异常指令包括所述写操作,且待写入数据对应的内存地址位于内核空间,所述信号处理函数从第二保留区域获取所述待写入数据;
所述信号处理函数向所述内核发送第四请求;所述第四请求,用于请求所述内核将所述待写入的数据写入重定向空间;所述重定向空间指的是与所述内核空间存在映射关系的地址空间。
6.如权利要求1所述的方法,其特征在于,所述信号处理函数获取所述第一模拟结果,包括:
所述信号处理函数获得第三上下文,所述第三上下文是在所述第一保留区域执行所述异常指令产生的;
所述信号处理函数从所述第三上下文中获取所述第一模拟结果。
7.如权利要求6所述的方法,其特征在于,所述信号处理函数获取所述第一模拟结果之后,还包括:
所述信号处理函数修改所述第三上下文,确定第四上下文;其中,所述第四上下文中的程序计数器指向所述异常指令的下一条指令;
所述信号处理函数向内核发送第五请求;所述第五请求,用于请求所述内核使用所述第四上下文恢复程序执行。
8.如权利要求1至7任一项所述的方法,其特征在于,所述信号处理函数将异常指令和第一跳转指令写入第一保留区域,包括:
所述信号处理函数获取用户程序中位于所述异常指令后的N条指令;N为大于等于0的整数;
所述信号处理函数将所述异常指令及所述N条指令写入所述第一保留区域;
所述信号处理函数将所述第一跳转指令写入第一保留区域;所述第一跳转指令位于所述异常指令和所述N条指令之后。
9.如权利要求1至7任一项所述的方法,其特征在于,所述信号处理函数将异常指令和第一跳转指令写入第一保留区域之前,还包括:
确定所述异常指令为复杂指令;所述复杂指令中包括访存操作及运算操作、多次访存操作或多次运算操作。
10.如权利要求9所述的方法,其特征在于,所述方法还包括:
确定所述异常指令为访存指令;
信号处理函数解析所述异常指令,确定所述异常指令的访存地址位于内核空间;
所述信号处理函数确定所述访存地址对应的第一重定向地址;所述第一重定向地址是位于重定向空间的地址;
所述信号处理函数向内核发送第二请求;所述第二请求用于请求所述内核根据所述第一重定向地址进行数据读写操作;
所述信号处理函数获取所述内核的读写结果,模拟执行所述异常指令,得到第二模拟结果。
11.如权利要求3所述的方法,其特征在于,所述方法还包括:
在用户程序启动时,设置第一保留区域和所述第二保留区域;或,
在首次为所述用户程序分配内核空间时,设置第一保留区域和所述第二保留区域。
12.如权利要求11所述的方法,其特征在于,所述方法还包括:
分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置不可读不可写不可执行;向所述第一保留区域写入异常指令时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置不可读不可写不可执行;或,
分配所述第一保留区域时,将所述第一保留区域对应的权限设置可写不可执行;执行所述第一保留区域时,将所述第一保留区域对应的权限设置不可写可执行;执行所述第一保留区域之后,将所述第一保留区域对应的权限设置可写不可执行。
13.如权利要求12所述的方法,其特征在于,所述方法还包括:
分配第二保留区域时,将所述第二保留区域对应的权限设置可读可写不可执行;或,
分配所述第二保留区域时,将所述第二保留区域对应的权限设置不可读不可写不可执行;对所述第二保留区域进行读操作或写操作时,将所述第二保留区域对应的权限设置可读可写不可执行;完成对所述第二保留区域读操作或写操作时,将所述第二保留区域对应的权限设置不可读不可写不可执行。
14.一种计算设备,其特征在于,包括:
存储器,用于存储程序指令;
处理器,用于调用所述存储器中存储的程序指令,按照获得的程序指令执行如权利要求1至13中任一项所述的方法。
15.一种计算机可读存储介质,其特征在于,包括计算机可读指令,当计算机读取并执行所述计算机可读指令时,使得如权利要求1至13中任一项所述的方法实现。
16.一种计算机程序产品,其特征在于,包括有可由计算机设备执行的计算机程序,当所述程序在计算机设备上运行时,使得所述计算机设备执行权利要求1至13任一所述方法的步骤。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202410466612.3A CN118069403B (zh) | 2024-04-18 | 2024-04-18 | 一种异常指令的处理方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202410466612.3A CN118069403B (zh) | 2024-04-18 | 2024-04-18 | 一种异常指令的处理方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN118069403A true CN118069403A (zh) | 2024-05-24 |
CN118069403B CN118069403B (zh) | 2024-09-06 |
Family
ID=91097565
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202410466612.3A Active CN118069403B (zh) | 2024-04-18 | 2024-04-18 | 一种异常指令的处理方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN118069403B (zh) |
Citations (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
EP0853278A2 (en) * | 1997-01-09 | 1998-07-15 | Sun Microsystems, Inc. | Fast traps for computer software instrumentation |
US20060150198A1 (en) * | 2004-12-03 | 2006-07-06 | Microsoft Corporation | Routing exceptions to operating system subsystems |
US20080307180A1 (en) * | 2007-06-06 | 2008-12-11 | Naoya Hattori | Virtual machine control program and virtual machine system |
CN110825489A (zh) * | 2019-10-21 | 2020-02-21 | 网易(杭州)网络有限公司 | 安卓模拟器的应用方法、装置和终端设备 |
US20210248029A1 (en) * | 2020-02-12 | 2021-08-12 | International Business Machines Corporation | Handling asynchronous memory errors on kernel text |
US20220035911A1 (en) * | 2020-07-31 | 2022-02-03 | RunSafe Security, Inc. | Active signaling in response to attacks on a transformed binary |
US11385974B1 (en) * | 2021-03-01 | 2022-07-12 | Google Llc | Uncorrectable memory error recovery for virtual machine hosts |
CN115495278A (zh) * | 2022-11-14 | 2022-12-20 | 阿里巴巴(中国)有限公司 | 异常修复方法、设备及存储介质 |
CN116225765A (zh) * | 2023-03-06 | 2023-06-06 | 支付宝(杭州)信息技术有限公司 | 一种在虚拟机中执行指令的方法和一种虚拟机监视器 |
-
2024
- 2024-04-18 CN CN202410466612.3A patent/CN118069403B/zh active Active
Patent Citations (9)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
EP0853278A2 (en) * | 1997-01-09 | 1998-07-15 | Sun Microsystems, Inc. | Fast traps for computer software instrumentation |
US20060150198A1 (en) * | 2004-12-03 | 2006-07-06 | Microsoft Corporation | Routing exceptions to operating system subsystems |
US20080307180A1 (en) * | 2007-06-06 | 2008-12-11 | Naoya Hattori | Virtual machine control program and virtual machine system |
CN110825489A (zh) * | 2019-10-21 | 2020-02-21 | 网易(杭州)网络有限公司 | 安卓模拟器的应用方法、装置和终端设备 |
US20210248029A1 (en) * | 2020-02-12 | 2021-08-12 | International Business Machines Corporation | Handling asynchronous memory errors on kernel text |
US20220035911A1 (en) * | 2020-07-31 | 2022-02-03 | RunSafe Security, Inc. | Active signaling in response to attacks on a transformed binary |
US11385974B1 (en) * | 2021-03-01 | 2022-07-12 | Google Llc | Uncorrectable memory error recovery for virtual machine hosts |
CN115495278A (zh) * | 2022-11-14 | 2022-12-20 | 阿里巴巴(中国)有限公司 | 异常修复方法、设备及存储介质 |
CN116225765A (zh) * | 2023-03-06 | 2023-06-06 | 支付宝(杭州)信息技术有限公司 | 一种在虚拟机中执行指令的方法和一种虚拟机监视器 |
Also Published As
Publication number | Publication date |
---|---|
CN118069403B (zh) | 2024-09-06 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US5303378A (en) | Reentrant protected mode kernel using virtual 8086 mode interrupt service routines | |
RU2374675C2 (ru) | Системы и способы использования синтезированных команд в виртуальной машине | |
US7661035B2 (en) | Method and system for instruction tracing with enhanced interrupt avoidance | |
US20130091568A1 (en) | Systems and methods for secure in-vm monitoring | |
JP2021532468A (ja) | メモリ・システム内に記憶されているメモリ保護テーブルを使用するメモリ保護ユニット | |
JP7128206B2 (ja) | 機能の使用を管理するための装置および方法 | |
US7506096B1 (en) | Memory segment emulation model for virtual machine | |
JP2021531583A (ja) | メモリ・システム内に記憶されている制御テーブルのための二分探索手順 | |
US11119778B2 (en) | Apparatus and method for controlling execution of instructions | |
US20220366036A1 (en) | An apparatus and method for handling exceptions | |
JP2022505011A (ja) | メモリ・アクセスを制御するための装置及び方法 | |
CN117573419B (zh) | 一种页面异常处理方法及装置 | |
US20040122834A1 (en) | Apparatus and method for switching mode in a computer system | |
JP7349437B2 (ja) | メモリ・アクセスにおける保護タグ・チェックの制御 | |
CN118069403B (zh) | 一种异常指令的处理方法 | |
US11216280B2 (en) | Exception interception | |
JP2024517627A (ja) | ケイパビリティを使用してメモリへのアクセスを制約するための技法 | |
CN111737656B (zh) | 面向应用程序的特权硬件资源访问方法及电子设备 | |
CN118093202B (zh) | 一种访存异常的处理方法、计算设备、存储介质及程序产品 | |
US20080072009A1 (en) | Apparatus and method for handling interrupt disabled section and page pinning apparatus and method | |
JP7369720B2 (ja) | アクションをトリガするための装置及び方法 | |
US20230161650A1 (en) | Method and apparatus for inter-process communication, and computer storage medium | |
Suann | Zircon on seL4 | |
TW202435061A (zh) | 位址相依檢查 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |