嵌入式软件堆栈溢出检测方法和装置与流程

文档序号:13804704阅读:476来源:国知局
嵌入式软件堆栈溢出检测方法和装置与流程

本发明主要应用于软件测试领域,具体为一种嵌入式软件堆栈溢出检测方法和装置。



背景技术:

面向特定应用的嵌入式系统一般会根据实际需求选择规格适中的mcu,采用c语言进行软件开发。在mcu的地址空间中,ram是一段连续分配的线性空间,全局变量、堆(heap)、堆栈(stack)都分配在这段有限的线性空间内,根据实际需要,嵌入式系统还可能把flash中一段代码重定位到一段ram空间内运行,以加快程序运行速度,提高系统实时性。但由于ram资源有限,不可能为堆栈分配太大的尺寸。堆栈尺寸设置过小、局部变量尺寸定义过大、中断优先级设置不合理、中断服务程序过长导致中断嵌套、递归调用、函数调用层次过深等程序设计不当之处都可能导致堆栈溢出。堆栈溢出会改变临近堆栈的ram空间中的内容,临近堆栈的ram空间的数据变化也会改变堆栈内容,从而造成程序运行异常,发生故障甚至导致重大事故。

为了确定堆栈空间的尺寸,需要根据源程序中每个函数的局部变量大小确定每个函数的堆栈使用量,然后根据编译器生成的函数调用列表为每个函数建立调用树,检查每棵调用树,确定从树根到树叶的调用路径的堆栈使用量,从中选出最大堆栈使用量,同时,还要仔细分析系统用到的所有中断,确定中断服务程序的堆栈使用量。但是,我们无法得知c标准库函数以及大值整数的乘除、浮点运算等对应的运行库函数的堆栈使用量,这种静态分析方式得到的数据并不完善,而且这种方式依赖于具体的应用和源程序实现方式,缺乏通用性。

专利文献cn201610080939.2公开了一种适用于多任务软件进程堆栈使用深度检测的方法,触发被测软件执行最大运行路径测试,通过任务堆栈区初始化值的变化判断堆栈使用量,这种方式需要开发人员分析被测软件,才能确定出最大运行路径,同时通过专用指令触发被测软件执行最大运行路径,违反了产品正常的使用过程,而且忽略了中断对堆栈的消耗,不能反映真实的堆栈使用情况。

如何在不影响软件正常运行的情况下检测堆栈使用情况,保证发生溢出时进行及时应对,仍是目前需要本领域技术人员迫切解决的一个技术问题。



技术实现要素:

为了解决上述问题,本发明提供了一种嵌入式软件堆栈溢出检测方法,设置一堆栈溢出缓冲区,隔离堆栈和全局变量分区,在不影响系统正常运行的情况下,在不受堆栈溢出影响的定时器中断服务程序中,周期检测堆栈使用量,将最大堆栈使用量和系统发生堆栈溢出后的部分上下文数据存入非易失性存储器,并通过控制led提示堆栈溢出情况。系统在实际环境中运行一段时间后,通过查看led状态以及读取非易失性存储器中的数据,便可以判断堆栈使用情况,通过保存的溢出上下文数据分析程序异常位置,从而调整堆栈尺寸或者调整程序设计,以提高系统运行的稳定性。

为了实现上述目的,本发明采用如下技术方案:

一种嵌入式软件堆栈溢出检测方法,包括以下步骤:

步骤1:通过链接文件将处理器随机存储器空间划分为堆栈区、堆栈溢出缓冲区和全局变量区;并在所述堆栈溢出缓冲区定义一个堆栈溢出缓冲数组;

步骤2:处理器上电,开启定时器;

步骤3:在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算最大堆栈使用量;

步骤4:判断所述最大堆栈使用量是否大于堆栈区尺寸,若是,判断为堆栈溢出,进入下一步;若否,返回步骤3;

步骤5:将溢出的上下文信息存入所述堆栈溢出缓冲数组;

步骤6:判断所述最大堆栈使用量是否小于或等于预设阈值,若是,根据堆栈溢出缓冲数组判断堆栈溢出位置。

所述步骤1中划分随机存储器空间的方法为:按从顶部到底部的顺序,将随机存储器空间划分为依次相邻的堆栈区、堆栈溢出缓冲区和全局变量区;尺寸关系为:

ram_size>=stack_size+stack_buf+app_ram_size

ram_size为随机存储器尺寸,stack_size为堆栈区尺寸,stack_buf为堆栈溢出缓冲区尺寸,app_ram_size为全局变量区尺寸。

所述步骤2还包括初始化堆栈指针位置、堆栈区数据和堆栈溢出缓冲数组,并初始化最大堆栈使用量为0。

所述步骤3具体包括:

步骤3.1:在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算当前堆栈使用量;

步骤3.2:判断当前堆栈使用量是否大于最大堆栈使用量,若是,将所述当前堆栈使用量赋值给最大堆栈使用量,若否,返回步骤3.1。

所述步骤3.1中当前堆栈使用量计算方法为:

当前堆栈使用量=stack_size+stack_buf-read_times

所述步骤6具体包括:

步骤6.1:判断所述最大堆栈使用量是否小于或等于预设阈值:如果小于,点亮led进行提示;如果等于,闪烁led灯进行提示;

步骤6.2:检查led状态,如果为点亮或者闪烁,读取最大堆栈使用量和堆栈溢出缓冲数组,根据所述堆栈溢出缓冲数组中的数据判断堆栈溢出位置。

其中,所述预设阈值为堆栈区尺寸+堆栈溢出缓冲区尺寸。

所述方法还包括步骤7:修改程序设计或者增加堆栈空间的尺寸,然后返回步骤1判断能否满足要求。

根据本发明的第二目的,本发明提供了一种计算机装置,用于嵌入式软件堆栈溢出检测,包括随机存储器、处理器及存储在随机存储器上并可在处理器上运行的计算机程序,所述处理器执行所述程序时实现以下步骤,包括:

接收用户对处理器随机存储器的空间划分,所述空间划分将随机存储器划分为堆栈区、堆栈溢出缓冲区和全局变量区,并接收在堆栈溢出缓冲区上设置的堆栈溢出缓冲区数组;

接收上电指令,开启定时器;

在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算最大堆栈使用量;

判断所述最大堆栈使用量是否大于堆栈区尺寸,若是,判断为堆栈溢出,进入下一步;若否,继续计算最大堆栈使用量;

将溢出的上下文信息存入所述堆栈溢出缓冲数组;

判断所述最大堆栈使用量是否小于或等于预设阈值,若是,根据堆栈溢出缓冲数组判断堆栈溢出位置。

根据本发明的第三目的,本发明提供了一种计算机可读存储介质,其上存储有嵌入式软件堆栈溢出检测的计算机程序,该程序被处理器执行时实现以下步骤:

接收用户对处理器随机存储器的空间划分,所述空间划分将随机存储器划分为堆栈区、堆栈溢出缓冲区和全局变量区,并接收在堆栈溢出缓冲区上设置的堆栈溢出缓冲区数组;

接收上电指令,开启定时器;

在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算最大堆栈使用量;

判断所述最大堆栈使用量是否大于堆栈区尺寸,若是,判断为堆栈溢出,进入下一步;若否,继续计算最大堆栈使用量;

将溢出的上下文信息存入所述堆栈溢出缓冲数组;

判断所述最大堆栈使用量是否小于或等于预设阈值,若是,根据堆栈溢出缓冲数组判断堆栈溢出位置。

本发明的有益效果:

(1)本发明的堆栈检测不影响软件的正常运行,在软件运行过程中实时检测堆栈使用情况。

(2)本发明堆栈溢出及使用量检测函数位于定时器中断服务程序中,即使发生堆栈溢出,mcu也会响应定时器中断,会执行堆栈检测函数。

(3)本发明设置了堆栈缓冲溢出区,隔离堆栈和全局变量分区,浅度的堆栈溢出不会影响全局变量,不会造成系统运行异常。

(4)本发明在堆栈溢出后,将关键的上下文数据存放在堆栈溢出缓冲区,将堆栈溢出缓冲区数据存入非易失性存储器,可以帮助开发人员判断溢出原因,检查程序缺陷。

附图说明

构成本申请的一部分的说明书附图用来提供对本申请的进一步理解,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。

图1为本发明的ram空间划分示意图。

图2为本发明的堆栈溢出及使用量检测方法流程图。

具体实施方式

下面结合附图与实施例对本发明作进一步说明。

应该指出,以下详细说明都是例示性的,旨在对本申请提供进一步的说明。除非另有指明,本文使用的所有技术和科学术语具有与本申请所属技术领域的普通技术人员通常理解的相同含义。

需要注意的是,这里所使用的术语仅是为了描述具体实施方式,而非意图限制根据本申请的示例性实施方式。如在这里所使用的,除非上下文另外明确指出,否则单数形式也意图包括复数形式,此外,还应当理解的是,当在本说明书中使用术语“包含”和/或“包括”时,其指明存在特征、步骤、操作、器件、组件和/或它们的组合。

在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互组合。

实施例一

本实施例提供了一种嵌入式软件堆栈溢出检测方法,如图1所示,包括以下步骤:

步骤1:通过链接文件将处理器随机存储器空间划分为堆栈区、堆栈溢出缓冲区和全局变量区;并在所述堆栈溢出缓冲区定义一个堆栈溢出缓冲数组;

步骤2:处理器上电,开启定时器;

步骤3:在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算最大堆栈使用量;

步骤4:判断所述最大堆栈使用量是否大于堆栈区尺寸,若是,判断为堆栈溢出,进入下一步;若否,返回步骤3;

步骤5:将溢出的上下文信息存入所述堆栈溢出缓冲数组;

步骤6:判断所述最大堆栈使用量是否小于或等于预设阈值,若是,根据堆栈溢出缓冲数组判断堆栈溢出位置。

所述步骤1中划分随机存储器空间的方法为:按从顶部到底部的顺序,将随机存储器空间划分为依次相邻的堆栈区、堆栈溢出缓冲区和全局变量区;尺寸关系为:

ram_size>=stack_size+stack_buf+app_ram_size

ram_size为随机存储器尺寸,stack_size为堆栈区尺寸,stack_buf为堆栈溢出缓冲区尺寸,app_ram_size为全局变量区尺寸。

所述步骤2还包括初始化堆栈指针位置、堆栈区数据和堆栈溢出缓冲数组,并初始化最大堆栈使用量为0。

所述步骤3具体包括:

步骤3.1:在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算当前堆栈使用量;

步骤3.2:判断当前堆栈使用量是否大于最大堆栈使用量,若是,将所述当前堆栈使用量赋值给最大堆栈使用量,若否,返回步骤3.1。

所述步骤3.1中当前堆栈使用量计算方法为:

当前堆栈使用量=stack_size+stack_buf-read_times

优选地,stack_buf为100字节。

所述步骤6具体包括:

步骤6.1:判断所述最大堆栈使用量是否小于或等于预设阈值:如果小于,点亮led进行提示;如果等于,闪烁led灯进行提示;

步骤6.2:检查led状态,如果为点亮或者闪烁,读取最大堆栈使用量和堆栈溢出缓冲数组,根据所述堆栈溢出缓冲数组中的数据判断堆栈溢出位置。

其中,所述预设阈值为堆栈区尺寸+堆栈溢出缓冲区尺寸。

所述方法还包括步骤7:修改程序设计或者增加堆栈空间的尺寸,然后返回步骤1判断能否满足要求。

为了更清楚的阐述本发明,所述嵌入式软件堆栈溢出检测方法具体为:

(1)根据堆栈的生长方向为自上向下增长,按照从顶部到底部的顺序,将ram空间划分为堆栈区、堆栈溢出缓冲区、全局变量区,根据需要和mcuram空间的尺寸,还可能设置代码重定位区。堆栈区尺寸为stack_size,栈底记为stack_bottom,设置为mcuram空间的最大地址;紧邻堆栈区,设置尺寸为100字节大小的堆栈溢出缓冲区;紧邻堆栈溢出缓冲区,设置尺寸为app_ram_size的全局变量区,mcu的ram尺寸记为ram_size,stack_size、app_ram_size和ram_size的关系为:

ram_size>=stack_size+100+app_ram_size(1)

(2)在堆栈溢出缓冲区定义一个包含100个单字节元素的数组,记为stack_overflow_buf[100];

(3)mcu上电初始化时,将堆栈指针sp初始化为stack_bottom,堆栈区数据和数组stack_overflow_buf全部初始化为0x55,最大堆栈使用量记为stack_size_max,初始化为0,然后开启一个周期为50ms的定时器。

(4)在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,判断堆栈使用情况。具体方法为:

读取次数记为read_times,初始化为0,以堆栈溢出缓冲区初始地址为首地址,以堆栈栈底为末地址,循环读取各个ram地址上的数据,如果读取到的数据等于0x55,读取地址加一,读取次数加一,如果读取到的数据不等于0x55,跳出ram读取循环。

当前最大堆栈使用量=stack_size+100-read_times(2)

(5)如果当前最大堆栈使用量小于或等于stack_size_max,返回步骤4,否则进入下一步;

(6)将当前最大堆栈使用量赋值给stack_size_max,存入非易失性存储器,如果stack_size_max小于或等于stack_size,返回步骤4,否则,判断为堆栈溢出,进入下一步;

(7)堆栈溢出后,溢出时的一部分上下文信息位于堆栈溢出缓冲区,将数组stack_overflow_buf作为堆栈溢出上下文数据,存入非易失性存储器;

(8)如果stack_size_max小于(stack_zize+100),此时的堆栈溢出不会影响全局变量区,不会造成系统运行异常,点亮led进行提示。如果stack_size_max等于(stack_zize+100),此时的堆栈溢出会影响全局变量区,造成系统运行异常,闪烁led灯进行提示。

(9)检查led状态,如果为点亮或者闪烁,通过专用设备(例如开发程序时的仿真器,烧写程序的烧录器),读取存储在非易失性存储器中的最大堆栈使用量和stack_overflow_buf。根据stack_overflow_buf数据判断堆栈溢出位置,修改程序设计或者增加堆栈空间的尺寸,然后继续按照步骤1-步骤8的顺序判断修改后的程序或堆栈尺寸能否满足要求。

实施例二

本实施例的目的是提供一种计算机装置。

基于以上目的,本实施例提供了一种计算机装置,用于嵌入式软件堆栈溢出检测,包括随机存储器、处理器及存储在随机存储器上并可在处理器上运行的计算机程序,所述处理器执行所述程序时实现以下步骤,包括:

接收用户对处理器随机存储器的空间划分,所述空间划分将随机存储器划分为堆栈区、堆栈溢出缓冲区和全局变量区,并接收在堆栈溢出缓冲区上设置的堆栈溢出缓冲区数组;

接收上电指令,开启定时器;

在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算最大堆栈使用量;

判断所述最大堆栈使用量是否大于堆栈区尺寸,若是,判断为堆栈溢出,进入下一步;若否,继续计算最大堆栈使用量;

将溢出的上下文信息存入所述堆栈溢出缓冲数组;

判断所述最大堆栈使用量是否小于或等于预设阈值,若是,根据堆栈溢出缓冲数组判断堆栈溢出位置。

实施例三

本实施例的目的是提供一种计算机可读存储介质。

基于以上目的,本实施例提供了一种计算机可读存储介质,其上存储有嵌入式软件堆栈溢出检测的计算机程序,该程序被处理器执行时实现以下步骤:

接收用户对处理器随机存储器的空间划分,所述空间划分将随机存储器划分为堆栈区、堆栈溢出缓冲区和全局变量区,并接收在堆栈溢出缓冲区上设置的堆栈溢出缓冲区数组;

接收上电指令,开启定时器;

在所述定时器的中断服务程序中,读取堆栈溢出缓冲区和堆栈区的数据,计算最大堆栈使用量;

判断所述最大堆栈使用量是否大于堆栈区尺寸,若是,判断为堆栈溢出,进入下一步;若否,继续计算最大堆栈使用量;

将溢出的上下文信息存入所述堆栈溢出缓冲数组;

判断所述最大堆栈使用量是否小于或等于预设阈值,若是,根据堆栈溢出缓冲数组判断堆栈溢出位置。

以上实施例二的计算机装置和实施例三的计算机可读存储介质,各步骤与方法实施例一相对应,具体实施方式可参见实施例一的相关说明部分。术语“计算机可读存储介质”应该理解为包括一个或多个指令集的单个介质或多个介质;还应当被理解为包括任何介质,所述任何介质能够存储、编码或承载用于由处理器执行的指令集并使处理器执行本发明中的任一方法。

本发明提供的堆栈溢出检测方法中,还检测了堆栈的使用量,且都在定时器中断服务程序中进行,即使发生堆栈溢出,mcu也会响应定时器中断,会执行堆栈检测函数。设置堆栈缓冲溢出区,隔离堆栈和全局变量分区,使得浅度的堆栈溢出不会影响全局变量,不会造成系统运行异常。关键的上下文数据存放在堆栈溢出缓冲区,将堆栈溢出缓冲区数据存入非易失性存储器,可以帮助开发人员判断溢出原因,检查程序缺陷。

本领域技术人员应该明白,上述的本发明的各模块或各步骤可以用通用的计算机装置来实现,可选地,它们可以用计算装置可执行的程序代码来实现,从而,可以将它们存储在存储装置中由计算装置来执行,或者将它们分别制作成各个集成电路模块,或者将它们中的多个模块或步骤制作成单个集成电路模块来实现。本发明不限制于任何特定的硬件和软件的结合。

上述虽然结合附图对本发明的具体实施方式进行了描述,但并非对本发明保护范围的限制,所属领域技术人员应该明白,在本发明的技术方案的基础上,本领域技术人员不需要付出创造性劳动即可做出的各种修改或变形仍在本发明的保护范围以内。

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