一种任务栈溢出监测方法及系统与流程

文档序号:13236390阅读:360来源:国知局
一种任务栈溢出监测方法及系统与流程

本申请涉及计算机领域,特别是涉及一种任务栈溢出监测方法及系统。



背景技术:

在操作系统中,如linux操作系统,为了提高操作系统运行效率,所有任务会共享同一物理地址空间,只有任务栈占用的内存空间是独立的,任何任务之间没有内存地址保护机制。一个任务栈的总长度是有限的,如果太长会导致内存空间浪费,如果太短可能导致任务栈溢出(任务栈溢出也称栈顶越界)。任务栈溢出意味着,在任务执行过程中将读写用于其它功能的内存内容。其它功能的内存内容有可能是本任务使用的内存内容,也有可能是其它任务使用的内存内容,从而导致发生各种异常现象,如任务崩溃、死机等。

现有的技术方案是确定一块位于任务栈末端的内存空间,将该内存空间设置为只读属性;该内存空间只能进行读操作,当任务执行过程中对该内存空间进行写操作时,会触发操作系统的地址访问异常中断;当监听到地址访问异常中断时,判断产生地址访问异常中断的任务是否任务栈溢出。

现有的技术方案缺点是:每个函数占用的内存空间中,并不是每个字节都会进行读写操作,有相当一部分内存内容是预留的,不会发生读写操作;即使是用于存储局部变量的空间,由于函数参数或者外部条件不一样,也不一定会进行写操作。如果任务栈末端的只读内存区恰好属于预留内存区,或者在一定条件下函数没有对只读内存区进行写操作,即使函数发生了任务栈溢出,也不会触发地址访问异常中断,此时任务栈末端内存区及只读内存区以外的内存区域已经被写入了错误数据。当有其它任务再次访问已经被写成错误数据的内存时,才会出现功能异常,并不能实时监测任务栈溢出现象,会漏报任务栈溢出现象。



技术实现要素:

有鉴于此,本申请提供一种任务栈溢出监测方法及系统。

具体地,本申请是通过如下技术方案实现的:

一种任务栈溢出监测方法,所述方法包括:

检测任务中函数栈操作状态;

若所述函数栈操作状态为预设的函数栈操作,则读取任务栈栈底地址;

将当前栈顶地址与所述任务栈栈底地址减去任务栈总长度得到的差值进行比较;

根据比较结果监测任务栈溢出。

一种任务栈溢出监测系统,所述系统包括:

检测函数栈操作单元,用于检测任务中函数栈操作状态;

读取栈底地址单元,用于若所述函数栈操作状态为预设的函数栈操作,则读取任务栈栈底地址;

比较单元,用于将当前栈顶地址与所述任务栈栈底地址减去任务栈总长度得到的差值进行比较;

监测任务栈溢出单元,用于根据比较结果监测任务栈溢出。

以上技术方案,将栈底地址减去任务栈总长度得到的差值与栈顶地址进行比较,根据比较结果能够实时监测任务栈溢出现象并报错,防止对其它任务甚至操作系统造成破坏,同时能够确保研发人员直接定位到造成任务栈溢出的代码位置和调用序列,方便研发人员快速查找问题。而且与现有技术方案相比,本方案不用占用额外的内存空间用于设置只读内存区,实时监测任务栈溢出现象,不会漏报任务栈溢出现象。

附图说明

为了更清楚地说明本发明实施例的技术方案,下面将对实施例描述中所需要的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明中记载的一些实施例,对于本领域普通技术人员来讲,还可以根据这些附图获得其他的附图。

图1是本申请一示例性实施例示出的任务栈溢出监测方法的一种实施流程图;

图2是本申请一示例性实施例示出的任务栈溢出监测方法的一段内存空间区域;

图3是本申请一示例性实施例示出的任务栈溢出监测方法的一种优选实施流程图;

图4是本申请一示例性实施例示出的任务栈溢出监测系统的一种结构示意图;

图5是本申请一示例性实施例示出的任务栈溢出监测系统的一种优选结构示意图。

具体实施方式

首先对本发明实施例所提供的一种任务栈溢出监测方法进行说明,该方法可以包括以下步骤:

检测任务中函数栈操作状态;

若所述函数栈操作状态为预设的函数栈操作,则读取任务栈栈底地址;

将当前栈顶地址与所述任务栈栈底地址减去任务栈总长度得到的差值进行比较;

根据比较结果监测任务栈溢出。

其中,任务中函数栈操作状态为函数在执行过程中进行压栈操作或进行退栈操作。这里对函数的压栈操作和退栈操作进行说明:每个函数调用时在任务栈空间中分配的一段内存区成为函数的栈帧,在任务执行过程中,进入一个函数时栈顶指针地址减去本函数栈帧大小,该操作称为压栈操作;退出函数时栈顶指针地址加上本函数栈帧大小,该操作称为退栈操作。进入函数和退出函数时,栈顶指针地址加减相同的值,确保调用一个函数前后栈顶指针地址保持原值不变。

在任务执行过程中,当前函数栈操作状态为压栈操作时,且在执行压栈操作指令之后,从任务基本信息数据结构中读取任务栈栈底地址和任务栈总长度,从栈顶寄存器中读取当前栈顶地址,将该任务栈栈底地址减去任务栈总长度得到的差值与当前栈顶寄存器中的栈顶地址进行比较。如果该任务栈栈底地址减去任务栈总长度的差值大于当前栈顶寄存器中的栈顶地址,则发生了任务栈溢出,否则就没有发生栈溢出。发生任务栈溢出时,立即记录现象异常信息并抛出异常,终止任务运行;没有发生任务栈溢出时,将继续执行原任务流程。

为了使本领域技术人员更好的理解本发明中的技术方案,这里将详细地对示例性实施例进行说明,其示例表示在附图中。下面的描述涉及附图时,除非另有表示,不同附图中的相同数字表示相同或相似的要素。以下示例性实施例中所描述的实施方式并不代表与本申请相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本申请的一些方面相一致的装置和方法的例子。基于本发明中的实施例,本领域普通技术人员所获得的所有其他实施例,都应当属于本发明保护的范围。

图1所示,为本发明一种任务栈溢出监测方法的实施流程图,其具体包括以下基本步骤:

s101,检测任务中函数栈操作状态;

根据本发明实施例的技术方案,首先需要确定的是任务执行过程中当前函数栈操作状态,即当前函数是否有压栈操作。如果函数没有压栈操作,则没有必要执行本方案的操作步骤。

对于函数的压栈操作、退栈操作前面已经做了详细描述,这里不再一一解释。假设在操作系统中有以下任务,主函数main函数,main函数调用func_a,函数func_a调用func_b函数。首先在该任务执行过程中,当执行main函数时,检测main函数是否有压栈操作;当执行main函数调用func_a时,检测func_a函数是否有压栈操作;当执行函数func_a调用func_b函数时,检测func_b函数是否有压栈操作。

s102,若所述函数栈操作状态为预设的函数栈操作,则读取任务栈栈底地址;

当前函数栈操作状态可能是进行压栈操作,也可能是进行退栈操作。当函数栈操作状态为压栈操作时,继续执行后续步骤,否则不再执行后续步骤;并且当函数执行压栈操作指令之后读取任务栈栈底地址。这里的任务栈栈底地址存放于任务基本信息的数据结构中。任务基本信息的数据结构中存放了任务名称、任务id(identity,身份)、任务运行状态、当前所运行的cpu(centralprocessingunit,中央处理器)id、任务栈总长度、任务栈栈底地址等。当操作系统创建一个任务时,会在内存中为该任务分配一块内存存放其任务基本信息数据结构,并初始化各项信息,包括任务栈总长度和任务栈栈底地址。在该任务的生命周期内,栈底地址一经初始化就不会再变化,任务栈总长度一经初始化可以保持不变,也可以动态调整。

如图2所示,这里以10000h-1000fh区域的内存区为例,操作系统将这段内存区域分配给任务栈内存空间。任务栈通常是沿地址减小的方向扩展,并且当操作系统创建一个任务时,在该任务的生命周期内,栈底地址一经初始化就不会再变化。由此显而易见,栈底地址是1000fh,所以从任务基本信息数据结构中读取的任务栈栈底地址为1000fh。

s103,将当前栈顶地址与所述任务栈栈底地址减去任务栈总长度得到的差值进行比较;

前面提到任务栈栈底地址和任务栈总长度存放于任务基本信息数据结构中,则需要从任务基本信息数据结构中读取任务栈栈底地址和任务栈总长度;而栈顶地址则存放于cpu中的专用栈顶寄存器中,随着任务不断执行栈顶地址实时变化,则需要从cpu中的专用栈顶寄存器中读取当前栈顶地址。在任务执行过程中,函数进行压栈操作进入函数时或函数进行退栈操作退出函数时,栈顶地址实时变化。这里简单说明任务栈总长度的计算方式。任务栈栈底地址存放在任务基本信息数据结构中,一经初始化就不会再变化,任务栈栈底地址不允许进行访问,意味着不会进行写操作,因此在计算任务栈总长度时,任务栈栈底地址并不会计算在里面。

前面提到在任务的生命周期内,栈底地址一经初始化就不会再变化,任务栈总长度一经初始化可以保持不变,也可以动态调整。因此我们可以得出在该任务的生命周期内,栈底地址是唯一的,不可变的,而任务栈总长度可以保持不变也可以动态调整,即存在两种情况,这里对这两种情况分别做下说明。

假设当前任务栈总长度是保持不变的,这里引用图2所示的内存空间区域,任务栈栈底地址为1000fh,任务栈内存空间为10000h-1000fh,根据上述任务栈总长度的计算方式,这里我们可以很容易计算得出任务栈总长度为15。任务栈栈底地址减去任务栈总长度得到一个差值10000h,这里我们可以将任务栈栈底地址减去任务栈总长度得到的差值10000h存放到任务基本信息数据结构中,即在任务基本信息数据结构中增加一列信息:最小栈顶地址。因此本发明在任务栈总长度保持不变的情况下只需要在任务启动时读取一次任务栈总长度,将任务栈栈底地址减去任务栈总长度得到的差值存放于任务基本信息数据结构中,在后续任务执行过程中,只需将当前栈顶地址与任务基本信息数据结构中的最小栈顶地址进行比较。在正常情况下,即没有发生任务栈溢出时,栈顶地址可以在10000h-1000eh之间变化。当栈顶地址为10000h时,此时栈顶地址和任务栈栈底地址减去任务栈总长度得到的差值相等,即当前栈顶地址与最小栈顶地址相等,这种情况属于任务栈溢出的临界情况。当栈顶地址小于最小栈顶地址10000h时,这时就发生了任务栈溢出。

假设当前任务栈总长度是可以动态调整的,任务栈栈底地址为1000fh,任务栈初始分配的内存空间为10000h-1000fh,根据上述计算任务栈总长度的计算方式,我们可以很容易计算出任务栈总长度为15,此时我们从任务基本信息数据结构中读取的任务栈总长度为15。由于任务栈总长度是可以动态调整的,即操作系统给任务栈分配的内存空间是可以动态调整的,我们根据上述计算任务栈总长度的计算方式,得出的任务栈总长度是可以变化的,计算出的任务栈总长度可能大于15,也可能小于15,任务栈栈底地址减去任务栈总长度得到的差值也是可以变化的。因此在任务执行过程中,我们需要每次从任务基本信息数据结构中重新读取任务栈总长度,将当前栈顶地址与任务栈栈底地址减去任务栈总长度得到的差值进行比较。当前栈顶地址小于任务栈栈底地址减去任务栈总长度得到的差值时,则发生了任务栈溢出。

s104,根据比较结果监测任务栈溢出;

当栈顶地址小于任务栈栈底地址减去任务栈总长度得到的差值时,此时发生了任务栈溢出现象。这里假设当栈顶地址为10001h时,当然栈顶地址不仅限于此,栈顶地址可以在10000h-1000eh之间变化,此时栈顶地址大于任务栈栈底地址减去任务栈总长度得到的差值,则没有发生任务栈溢出,继续执行原任务流程;如果当前栈顶地址为f000h时,当然栈顶地址不仅限于此,只要满足小于10000h,此时栈顶地址小于任务栈栈底地址减去任务栈总长度得到的差值,则发生了任务栈溢出。

在本发明优选实施例中,可以进一步在s104之后增加任务栈溢出处理机制,如图3所示。

s105,发生任务栈溢出时,记录现象异常信息并抛出异常,终止任务运行。

当栈顶地址小于任务栈栈底地址减去任务栈总长度得到的差值时,此时发生了任务栈溢出现象,立即记录现象异常信息并抛出异常,终止任务运行。这样,任何函数在刚发生任务栈溢出时,尚未对任务栈之外的内存空间执行写操作时,系统就会实时发现任务栈溢出现象。例如这里的现象异常信息可以为函数调用序列,当然现象异常信息不仅限于此,也可以是正在执行的程序指令地址、cpu寄存器信息等。操作系统会将现象异常信息记录到运行日志文件中,当然也可以将现象异常信息记录到其它文件中,也可以直接弹出对话框,将现象异常信息直接展示出来。操作系统可以通过警告或错误形式的窗口来提示研发人员任务栈溢出,并直接终止任务运行。后续研发人员可以根据记录的现象异常信息定位问题,可以迅速解决问题。

本领域普通技术人员可以理解:实现上述方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成,前述的程序可以存储于计算机可读取存储介质中,该程序在执行时,执行包括上述方法实施例的步骤;而前述的存储介质包括:rom、ram、磁碟或者光盘等各种可以存储程序代码的介质。

与前述一种任务栈溢出监测方法的实施例相对应,本申请还提供了一种任务栈溢出监测系统的实施例。参照图4所示,包括检测函数栈操作单元210、读取栈底地址单元220、比较单元230、监测任务栈溢出单元240。

所述检测函数栈操作单元210,用于检测任务中函数栈操作状态,并将检测结果发送至读取栈底地址单元220;

所述读取栈底地址单元220,用于若函数栈操作为预设的函数栈操作,读取任务栈栈底地址,并将任务栈栈底地址发送给比较单元230;

所述比较单元230,用于将栈顶地址与任务栈栈底地址减去任务栈总长度得到的差值进行比较,并将比较结果发送至监测任务栈溢出单元240;

所述监测任务栈溢出单元240,用于根据比较结果监测任务栈溢出。

参见图5所示,本发明实施例所提供的任务栈溢出监测系统,还可以包括:

警告单元250,用于发生任务栈溢出时,记录现象异常信息并抛出异常,终止任务运行。

上述提供的任务栈溢出监测系统,由于利用栈顶地址与任务栈栈底地址减去任务栈总长度得到的差值进行比较,根据比较结果来监测任务栈溢出,能够实时发现任务栈溢出现象并报错,不会漏报任务栈溢出现象,防止任务对其它任务甚至整个操作系统造成破坏,同时能够帮助研发人员定位问题的代码位置和调用序列,从而快速解决问题。

上述系统中各个单元的作用实现过程具体详见上述方法中对应步骤的实现过程,在此不再赘述。

对于系统实施例而言,由于其基本对应于方法实施例,所以相关之处参见方法实施例的部分说明即可。以上所描述的系统实施例仅仅是示意性的,其中所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本申请方案的目的。本领域普通技术人员在不付出创造性劳动的情况下,即可以理解并实施。本发明可用于众多操作系统中。例如:windows操作系统、linux操作系统、ios操作系统、安卓操作系统等等。

本发明可以在由计算机执行的计算值可执行指令的一般上下文中描述,例如程序模块。一般地,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。也可以在分布式计算环境中实践本发明,在这些分布式计算环境中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于包括存储设备在内的本地和远程计算机存储介质中。

以上所述仅是本发明的具体实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1