本申请涉及电数字数据处理领域,尤其涉及任务栈溢出检测方法及系统。
背景技术:
操作系统任务栈大小通常是任务创建时预先设置确定的,运行过程中由于局部变量占用栈空间过大或者函数调用时嵌套的函数层次过深等,导致栈溢出。栈溢出时栈指针超出了预先分配的栈空间范围,导致与栈空间相邻的其它内存被覆盖或者非法访问。其它内存可能是其它任务使用的内存范围,被覆盖后导致系统致命的异常现象发生,如任务奔溃、死机等。
目前通常用两类方法检测任务栈溢出。一是借助处理器的硬件特性,使用处理器的内存管理器件如mpu(memoryprotectunit,内存保护单元)或者mmu(memorymanageunit,内存管理单元),在任务创建时,将任务栈空间栈底的几个字节设置为只读的属性。栈溢出发生后,试图对栈底的内存写入数据,会触发硬件的访问异常,从而被系统检测到。但该方法需要处理器的硬件支持。二是软件动态检测,增加编译后的代码段内容。例如借助gcc(gnucompilercollection,gnu编译器套件)的编译选项,在系统每个函数的开头插入一个函数调用,被调用的函数中获取当前的sp(stackpointer,栈指针),判断sp指针是否超出了当前运行的任务栈空间范围,如果超出则上报给系统,终止当前任务。这样相当于每个函数都增加了额外的一小段函数调用代码,会增加编译后整体镜像的大小。该方法需要处理器有较大的flash和ram。
随着万物互联和5g的推出,将来联网的设备将达到万亿。iot(internetofthings,物联网)设备由于实时性、低功耗的要求以及资源受限的特点,传统的操作系统并不适宜,需要新的iot操作系统。相应地,iot设备处理器通常简单,设备资源有限,硬件上不具有mpu或者mmu这些内存管理器件或者没有充分的系统资源来使用硬件保护,也没有太大的flash和ram,不能在每个函数中都插入额外的代码。因而需要开发适用于iot操作系统的任务栈溢出检测和处理方法。
技术实现要素:
为了克服现有技术中存在的不足,本发明提供一种任务栈溢出检测方法及系统,其不需要处理器具备硬件的支持,也不会给函数增加额外的代码、不增加编译后镜像的大小,特别适用于iot设备的操作系统。
为解决上述技术问题,根据本发明的第一方面,提供一种任务栈溢出检测方法,该方法包括:
响应于任务创建,根据分配的任务栈信息确定栈底位置,对栈底的最后n个字节赋值;
响应于系统调度,任务在各个状态之间切换,不定时检查任务栈空间栈底的最后n个字节是否与预先的赋值相等,其中任务状态包括创建、就绪、运行、等待、挂起和终止状态;
响应于任务栈空间栈底的最后n个字节与预先的赋值不相等,确定存在任务栈溢出。
在实施例中,所述方法还包括:响应于确定存在任务栈溢出,触发异常并报告给系统,结束当前任务;获取并打印异常栈空间栈底地址以及地址前后的内存内容;获取并打印当前任务的上下文信息。
在实施例中,所述不定时检查包括:响应于任务切换,检查被切换的任务栈;和/或响应于发生中断但没有发生任务切换,检查被中断的任务栈;和/或响应于任务主动让出中央处理单元,检查自身的任务栈;和/或响应于任务主动结束或者被杀死,检查要终止的任务栈。
为解决上述技术问题,根据本发明的第二方面,提供一种任务栈溢出检测系统,该系统包括:
栈底确定和赋值模块,用于响应于任务创建,根据分配的任务栈信息确定栈底位置,对栈底的最后n个字节赋值;
检查模块,用于响应于系统调度,任务在各个状态之间切换,不定时检查任务栈空间栈底的最后n个字节是否与预先的赋值相等,其中任务状态包括创建、就绪、运行、等待、挂起和终止状态;
溢出确定模块,用于响应于任务栈空间栈底的最后n个字节与预先的赋值不相等,确定存在任务栈溢出。
为解决上述技术问题,根据本发明的第三方面,提供一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现本发明的任务栈溢出检测方法的步骤。
为解决上述技术问题,根据本发明的第四方面,提供一种计算机设备,包括处理器、存储器及存储在所述存储器上并可在所述处理器上运行的计算机程序,其中所述处理器执行所述计算机程序时实现本发明的任务栈溢出检测方法的步骤。
基于操作系统运行时的调度,不同任务之间的切换导致任务自身在各个状态之间的切换,本发明根据任务运行时状态的切换,不定时进行任务栈溢出检测,不需要启动额外的定时检测任务或者定时检测中断来周期性的对任务栈检查,可以节省iot设备的有限资源。同时,不需要处理器具备硬件的支持,也不会给函数增加额外的代码、不增加编译后镜像的大小,特别适用于iot设备的操作系统。
结合附图阅读本发明实施方式的详细描述后,本发明的其它特点和优点将变得更加清楚。
附图说明
图1为任务状态之间的切换示意图;
图2为根据本发明方法的一实施例的流程图;
图3为根据本发明系统的一实施例的框图。
为清晰起见,这些附图均为示意性及简化的图,它们只给出了对于理解本发明所必要的细节,而省略其他细节。
具体实施方式
下面参照附图对本发明的实施方式和实施例进行详细说明。
通过下面给出的详细描述,本发明的适用范围将显而易见。然而,应当理解,在详细描述和具体例子表明本发明优选实施例的同时,它们仅为说明目的给出。
操作系统的任务有创建、就绪、运行、等待、挂起、终止状态,系统运行时任务会在各个状态之间切换,如图1所示。系统在开始调度运行后,cpu(中央处理单元)要么是在执行某个任务,要么是在执行中断处理。中断处理时cpu使用中断模式下分配的特定栈空间,一般足够大,不容易发生栈溢出。而且为了中断的嵌套和实时性,真正的中断处理流程比较简单,复杂的操作也都放置到了任务中执行,所以,cpu多数情况下是在执行某个任务。
图2示出了根据本发明的任务栈溢出检测方法的一优选实施例的流程图,其根据cpu的调度,在任务创建时执行栈空间设置,不同的任务之间切换,导致任务自身在各个状态之间切换时,执行不定时栈溢出检测。
在步骤s202,任务创建时,根据分配的任务栈信息,如栈的起始地址和大小等,确定栈底的位置,并对栈底的最后n个字节赋值,n根据任务栈大小设置,例如为4到16之间的整数如4、8等,赋值可使用随机数进行。作为一个实例,可以对栈底的最后4个字节,写入一个随机的数字作为幻数。
在步骤s204,系统调度,任务运行时,不定时判断任务栈空间栈底的最后4个字节,是否与设置的幻数相等,如果不相等,则发生了栈溢出。不定时的检测有下面四种场景:
1)当运行态的任务放弃cpu,如等待设备i/o口变化或者其它事件(延迟的时间、信号量、互斥、队列数据、消息等)进入等待态,自身挂起进入挂起态,或者被高优先级的任务抢占进入就绪态时,需要触发任务切换。任务切换时,检查被切换的任务栈;
2)当运行态的任务被中断打断时,任务进入就绪态。开始执行中断处理流程,流程结束后如果发生了任务切换,则执行1)中的流程,检查被切换的任务栈;如果中断结束后没有发生任务切换,而中断的复杂处理流程是在任务中完成的,此时检查被中断的任务栈;
3)当运行态的任务自己主动放弃cpu时,如调用k_yield函数,任务进入就绪态,此时检查自身的任务栈;
4)当运行态的任务结束时,无论是自己结束还是被其它任务杀死,任务进入终止态,此时检查要结束的任务栈。
在步骤s206,响应于在上面任一场景下判断出任务栈空间栈底的最后4个字节与预先设置的幻数不相等,确定存在任务栈溢出。
在实施例中,在确定栈溢出发生时,触发一个异常,上报给系统,并结束栈溢出的任务,获取并打印当前任务栈底地址以及地址前后的内存内容,获取并打印任务的上下文信息(包括程序状态寄存器的值、链接寄存器的值、pc寄存器的值以及r0~r12寄存的值)。技术人员可根据上下文信息和栈上的内容,排查栈溢出原因。
图3示出了根据本发明的任务栈溢出检测系统的一优选实施例的框图,该系统包括:栈底确定和赋值模块302,用于响应于任务创建,根据分配的任务栈信息确定栈底位置,对栈底的最后n个字节赋值;检查模块304,用于响应于系统调度,任务在各个状态之间切换,不定时检查任务栈空间栈底的最后n个字节是否与预先的赋值相等,其中任务状态包括创建、就绪、运行、等待、挂起和终止状态;溢出确定模块306,用于响应于任务栈空间栈底的最后n个字节与预先的赋值不相等,确定存在任务栈溢出。
在实施例中,检查模块304包括:第一检查子模块,用于响应于任务切换,检查被切换的任务栈;和/或第二检查子模块,用于响应于发生中断但没有发生任务切换,检查被中断的任务栈;和/或第三检查子模块,用于响应于任务主动让出中央处理单元,检查自身的任务栈;和/或第四检查子模块,用于响应于任务主动结束或者被杀死,检查要终止的任务栈。
在另一实施例中,本发明系统还包括:报告模块,用于响应于确定存在任务栈溢出,触发异常并报告给系统,结束当前任务;打印模块,用于获取并打印异常栈空间栈底地址以及地址前后的内存内容;获取模块,用于获取并打印当前任务的上下文信息。
在此所述的多个不同实施方式或者其特定特征、结构或特性可在本发明的一个或多个实施方式中适当组合。另外,在某些情形下,只要适当,流程图中和/或流水处理描述的步骤顺序可修改,并不必须精确按照所描述的顺序执行。另外,本发明的多个不同方面可使用软件、硬件、固件或者其组合和/或执行所述功能的其它计算机实施的模块或装置进行实施。本发明的软件实施可包括保存在计算机可读介质中并由一个或多个处理器执行的可执行代码。计算机可读介质可包括计算机硬盘驱动器、rom、ram、闪存、便携计算机存储介质如cd-rom、dvd-rom、闪盘驱动器和/或具有通用串行总线(usb)接口的其它装置,和/或任何其它适当的有形或非短暂计算机可读介质或可执行代码可保存于其上并由处理器执行的计算机存储器。本发明可结合任何适当的操作系统使用。
除非明确指出,在此所用的单数形式“一”、“该”均包括复数含义(即具有“至少一”的意思)。应当进一步理解,说明书中使用的术语“具有”、“包括”和/或“包含”表明存在所述的特征、步骤、操作、元件和/或部件,但不排除存在或增加一个或多个其他特征、步骤、操作、元件、部件和/或其组合。如在此所用的术语“和/或”包括一个或多个列举的相关项目的任何及所有组合。
前面说明了本发明的一些优选实施例,但是应当强调的是,本发明不局限于这些实施例,而是可以本发明主题范围内的其它方式实现。本领域技术人员可以在本发明技术构思的启发和不脱离本发明内容的基础上对本发明做出各种变型和修改,这些变型或修改仍落入本发明的保护范围之内。
1.一种任务栈溢出检测方法,其特征在于,所述方法包括:
响应于任务创建,根据分配的任务栈信息确定栈底位置,对栈底的最后n个字节赋值;
响应于系统调度,任务在各个状态之间切换,不定时检查任务栈空间栈底的最后n个字节是否与预先的赋值相等,其中任务状态包括创建、就绪、运行、等待、挂起和终止状态;
响应于任务栈空间栈底的最后n个字节与预先的赋值不相等,确定存在任务栈溢出。
2.根据权利要求1所述的方法,其特征在于,所述方法还包括:
响应于确定存在任务栈溢出,触发异常并报告给系统,结束当前任务;
获取并打印异常栈空间栈底地址以及地址前后的内存内容;
获取并打印当前任务的上下文信息。
3.根据权利要求1所述的方法,其特征在于,所述不定时检查包括:
响应于任务切换,检查被切换的任务栈;和/或
响应于发生中断但没有发生任务切换,检查被中断的任务栈;和/或
响应于任务主动让出中央处理单元,检查自身的任务栈;和/或
响应于任务主动结束或者被杀死,检查要终止的任务栈。
4.根据权利要求1所述的方法,其特征在于,所述任务栈信息包括栈的起始地址和大小。
5.根据权利要求1所述的方法,其特征在于,n在4到16之间。
6.根据权利要求1所述的方法,其特征在于,赋值采用随机数进行。
7.一种任务栈溢出检测系统,其特征在于,所述系统包括:
栈底确定和赋值模块,用于响应于任务创建,根据分配的任务栈信息确定栈底位置,对栈底的最后n个字节赋值;
检查模块,用于响应于系统调度,任务在各个状态之间切换,不定时检查任务栈空间栈底的最后n个字节是否与预先的赋值相等,其中任务状态包括创建、就绪、运行、等待、挂起和终止状态;
溢出确定模块,用于响应于任务栈空间栈底的最后n个字节与预先的赋值不相等,确定存在任务栈溢出。
8.根据权利要求7所述的系统,其特征在于,所述系统还包括:
报告模块,用于响应于确定存在任务栈溢出,触发异常并报告给系统,结束当前任务;
打印模块,用于获取并打印异常栈空间栈底地址以及地址前后的内存内容;
获取模块,用于获取并打印当前任务的上下文信息。
9.根据权利要求7所述的系统,其特征在于,所述检查模块包括:
第一检查子模块,用于响应于任务切换,检查被切换的任务栈;和/或
第二检查子模块,用于响应于发生中断但没有发生任务切换,检查被中断的任务栈;和/或
第三检查子模块,用于响应于任务主动让出中央处理单元,检查自身的任务栈;和/或
第四检查子模块,用于响应于任务主动结束或者被杀死,检查要终止的任务栈。
10.根据权利要求7所述的系统,其特征在于,n在4到16之间。
技术总结