CN102012833A - 基于编译过程中间结果的静态堆栈检测方法 - Google Patents

基于编译过程中间结果的静态堆栈检测方法 Download PDF

Info

Publication number
CN102012833A
CN102012833A CN2010105398604A CN201010539860A CN102012833A CN 102012833 A CN102012833 A CN 102012833A CN 2010105398604 A CN2010105398604 A CN 2010105398604A CN 201010539860 A CN201010539860 A CN 201010539860A CN 102012833 A CN102012833 A CN 102012833A
Authority
CN
China
Prior art keywords
function
storehouse
node
call
detection method
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.)
Pending
Application number
CN2010105398604A
Other languages
English (en)
Inventor
程胜
石文臣
张惠臻
孙磊
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
BEIJING SHENZHOU AEROSPACE SOFTWARE TECHNOLOGY Co Ltd
Original Assignee
BEIJING SHENZHOU AEROSPACE SOFTWARE TECHNOLOGY Co Ltd
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by BEIJING SHENZHOU AEROSPACE SOFTWARE TECHNOLOGY Co Ltd filed Critical BEIJING SHENZHOU AEROSPACE SOFTWARE TECHNOLOGY Co Ltd
Priority to CN2010105398604A priority Critical patent/CN102012833A/zh
Publication of CN102012833A publication Critical patent/CN102012833A/zh
Pending legal-status Critical Current

Links

Landscapes

  • Debugging And Monitoring (AREA)

Abstract

本发明涉及一种基于编译过程中间结果的静态堆栈检测方法,包括以下步骤:1)获得每个函数的栈帧的大小;2)获得每个函数的调用路径;3)对所有的函数调用关系建立函数调用图;4)遍历整个函数调用图,得到所有以main函数为起点、以底层的子函数为终点的路径。本发明提供的堆栈检测方法,利用了编译器的中间结果,大大的降低了开发的难度,且功能专一,运行效率高。源代码完全自主开发,对于提高敏感领域中嵌入式软件的质量,是一种很好的尝试。

Description

基于编译过程中间结果的静态堆栈检测方法
技术领域
本发明涉及一种基于编译过程中间结果的静态堆栈检测方法,属于编译器应用技术领域。
背景技术
C语言使用堆栈来存储局部变量和传递函数的参数,所以,如果函数的调用层数过多或者出现了递归调用,就非常容易使得堆栈上的内存需求超过了最大能够使用的空间限制,产生堆栈溢出。在普通的PC系统中,堆栈溢出并不是一个很明显的问题,一是因为很多系统中含有存储器管理单元(MMU),可以提供对堆栈内存空间的保护。二是因为普通PC系统存储器容量较大,可以分配给堆栈足够的内存空间,但是在内存容量受限制且大多不具备内存保护机制的嵌入式设备上,堆栈溢出经常会出现,而且一旦出现,往往意味着整个系统崩溃。所以在对嵌入式的C代码进行检查的时候,堆栈溢出检查是一个很重要的方面。
目前,在堆栈分析方面,还没有太多成熟的工具可用,唯一可以使用的是商用分析工具stackAnalyzer。这款软件可以自动分析出应用程序中最差情况下的堆栈使用情况;分析结果以标注的形式在调用关系图和控制流图中显示。它可以计算出任何一个函数的堆栈使用情况,并且起始点可以任意选取,也可以预报可能出现的堆栈溢出,以及优化对堆栈的使用。但是,这款软件是一个需要付费的商用产品,且价格较高。同时,由于没有源代码,无法对其本身的安全性进行评估,因此不能在航天软件开发上进行应用。
为了检测到是否有堆栈溢出错误发生,实际上是要监测在每个函数被调用时堆栈上存在的栈帧数目以及每个栈帧的内存需求。但由于栈帧的增减变化是在运行时动态地表现出来的,所以,静态的堆栈溢出检查有很大的困难。主要体现在以下两个方面:
第一,如何获得每个函数的栈帧的大小,也就是栈帧的内存需求。每个函数都可以定义任意数目和类型的临时变量以及输入参数,如何能够比较准确地计算所有这些变量和参数使用的内存大小。
第二,如何统计整个程序的函数调用情况。堆栈上栈帧的数目和顺序是随着函数调用序列而动态变化的,如何能够精确地跟踪程序中所有从main函数开始的调用序列对于溢出检测有着决定性的影响。用C语言写的源程序分布在不同的文件中,每个文件都包含了若干个函数,如何从这些代码中分析出每条函数调用序列。
发明内容
为了解决上述问题,为了保证堆栈的安全性,在分析了国内外堆栈检查技术的基础上,采用了John Regehr提出的通过对通用寄存器和中断控制寄存器的状态进行建模来检测堆栈溢出方法的思想。该方法将程序的运行过程表示为一个状态迁移流程图,通过对这个图的分析来判断是否存在堆栈溢出的情况。借鉴这样的思想,本发明提出了一种基于编译过程中间结果的静态堆栈检测方法,该方法对建立图和分析的方法进行了较大的改进。
本发明采用的技术方案如下:
一种基于编译过程中间结果的静态堆栈检测方法,其特征在于包括以下步骤:
1)获得每个函数的栈帧的大小;
2)获得每个函数的调用路径;
3)对所有的函数调用关系建立函数调用图;
4)遍历整个函数调用图,得到所有以main函数为起点、以底层的子函数为终点的路径。
进一步地:
在所述步骤1)中,通过分析编译器为每个函数生成的汇编代码段,从每个函数的代码段的调整栈顶指针语句中获得每个函数的栈帧的大小。
在所述步骤2)中,分析编译器为每个函数产生的RTL代码,寻找其中的调用指令,从而找到所有函数的调用关系。
在所述步骤3)中,函数调用关系图的定义如下:
函数调用关系图中的节点是程序中所有函数的集合,图中的边表示函数之间的调用关系,如果函数间存在调用关系,那么节点间通过有向弧相连接,这个有向弧从调用节点指向被调用节点,如果调用关系图中存在环,说明程序中存在递归调用。
所述步骤4)进一步包括以下步骤:
将图中所有的节点标记为未被访问的;
将图中所有的边标记为空;
堆栈大小初始化为零;
遍历函数调用关系图;
如果节点u正在被访问,则计算函数u使用的堆栈大小并加到总的堆栈大小中;
如果总的堆栈大小大于预设的堆栈最大值,则堆栈溢出;
如果节点u的邻居节点v被访问过了且v不是u的祖先节点则表明存在环;
如果节点v未被访问,则将u标记为v的祖先节点,然后以v为参数继续调用遍历函数;
通过该遍历算法并结合堆栈计算方法计算出堆栈使用的大小。
本发明的优点是:本发明提供的堆栈检测方法,利用了编译器的中间结果,大大的降低了开发的难度,且功能专一,运行效率高。源代码完全自主开发,对于提高敏感领域中嵌入式软件的质量,是一种很好的尝试。
具体实施方式
本发明提供了一种基于编译过程中间结果的静态堆栈检测方法。该方法包括以下步骤:
一种基于编译过程中间结果的静态堆栈检测方法,其特征在于包括以下步骤:
1)获得每个函数的栈帧的大小;
2)获得每个函数的调用路径;
3)对所有的函数调用关系建立函数调用图;
4)遍历整个函数调用图,得到所有以main函数为起点、以底层的子函数为终点的路径。
下面详细说明
1.获得函数堆栈大小的方法是分析编译过程生成的汇编代码。为了能够调整栈顶指针和栈帧指针,编译器会为每个函数都生成如下一段特殊的汇编代码,称为函数的“序言”。
Figure BSA00000342189500031
序言最后一句的作用,就是调整栈顶指针,为临时变量留出足够的内存空间。在函数test中,共定义了两个整数类型的临时变量,需要使用8个字节的栈空间,所以,在最后一句中,从栈顶指针减去了8。这个数值是在编译器对整个函数代码进行了解析之后计算出来的,从这句汇编中就可以知道一个函数中所有的临时变量总的内存大小,而不需要再去解析C代码。
2.计算出每个函数的堆栈使用仅仅是完成了分析的第一步,由于堆栈内存随着函数的调用而动态地变化,因此需要知道整个程序中所有函数的调用路径。执行入口必须是main函数,所以,所有在执行时会被调用到的函数,一定是出现在一棵以每个函数为树节点,main函数作为根节点的调用关系树上。
从C代码中直接解析得到函数调用关系图是比较困难的。可行的算法需要两次遍历所有代码。在第一次遍历中,需要分析出所有定义的函数名,构成一个集合,然后再进行二次遍历,在每个函数中搜索函数调用语句,搜索的依据就是所有函数名的集合。这种方法实现起来比较复杂,也需要词法和语法分析的支持,效率也很低。
从函数堆栈分析的经验可以看出,恰当地利用编译器的结果,可以大大地降低分析的难度。同时,由编译器进行语法词法分析,也能很好地保证分析的准确性。与堆栈使用分析不同的是,在分析调用关系时,使用的是另一种编译器的中间结果一一RTL代码。RTL语言(Register Transfer Language寄存器转换语言)用描述指令行为的代数形式逐条地描述了待输出的指令。一个函数的RTL是由insn组成的双向链。在RTL指令中,有一种专门表示函数调用的指令-call_insn。Call指令有两个操作数,如下所示:
(call(mem:fm addr)nbytes)
这里,nbytes是一个操作数,代表传给子程序的参数的字节数,fm是机器方式,addr代表被调用子程序的地址。
RTL代码以函数为单位,每个函数的RTL指令形成一个链表,可以将这个链表输出到一个外部文件来进行分析。对下面的这段C代码:
Figure BSA00000342189500041
生成的RTL代码如下所示:
Figure BSA00000342189500042
从RTL代码中标为深黑色的部分可以看出,RTL被输出到文件中以后,call指令中会包含被调用的函数名称,例如从上面的call指令我们可以清楚地知道,main函数在运行过程中调用了test函数。这样,通过对RTL中的call指令的分析,就可以方便地找到所有的函数调用关系。同时,RTL代码中含有的Function标注,也可以帮助我们找到所有源代码中定义的函数。这种从RTL代码中得到函数调用关系图的方法实现简单,同时具有很高的准确性,为最终的系统设计所采用。
3.调用图分析算法:为了能够准确地知道程序运行中每一时刻的堆栈使用情况,必须对程序中的所有的函数调用关系进行建模。本发明采用了函数调用图的模型。
函数调用关系图的定义如下:
函数调用关系图中的节点是程序中所有函数的集合,图中的边表示函数之间的调用关系。如果函数间存在调用关系,那么节点间会通过有向弧相连接,这个有向弧从调用节点指向被调用节点。如果调用关系图中存在环,说明程序中存在递归调用。
有了函数调用关系图,可以通过遍历算法得出以main函数为起点的调用序列,结合上面的堆栈大小的计算方法,就可以算出堆栈使用的情况。
3.遍历整个函数调用图:由于C语言的语法规定所有的可执行程序都必须以main函数作为入口点,所以,遍历整个函数调用图,等价于找出所有的以main为起点,以底层的子函数(没有调用其他任何函数)为终点的路径。
Figure BSA00000342189500051
以上这个算法为函数调用关系图遍历算法,即:
·将图中所有的节点标记为未被访问的;
·将图中所有的边标记为空;
·堆栈大小初始化为零;
·遍历函数调用关系图;
·如果节点u正在被访问,则计算函数u使用的堆栈大小并加到总的堆栈大小中;
·如果总的堆栈大小大于预设的堆栈最大值,则堆栈溢出;
·如果节点u的邻居节点v被访问过了且v不是u的祖先节点则表明存在环;
·如果节点v未被访问,则将u标记为v的祖先节点,然后以v为参数继续调用遍历函数;
通过该遍历算法并结合堆栈计算方法可以计算出堆栈使用的大小。
使用本发明方法我们实现了一个堆栈溢出静态检查工具,成为航天嵌入式软件开发环境的一个组成部分,由于应用于航天,所有工具本身需要具有很高的质量。所有要经过正确性和时间率的检验,我们对该工具进行了充分的测试,通过进行单元测试、功能测试和性能测试,证明堆栈检测程序实现了设计的目的,正确性不存在问题。同时在性能上也符合理论的算法分析结果,其时间复杂度同代码量的增长成线性关系,符合可用性的要求。目前该工具在航天领域已经得到应用,没有发现问题。

Claims (5)

1.一种基于编译过程中间结果的静态堆栈检测方法,其特征在于包括以下步骤:
1)获得每个函数的栈帧的大小;
2)获得每个函数的调用路径;
3)对所有的函数调用关系建立函数调用图;
4)遍历整个函数调用图,得到所有以main函数为起点、以底层的子函数为终点的路径。
2.如权利要求1所述的基于编译过程中间结果的静态堆栈检测方法,其特征在于:
在所述步骤1)中,通过分析编译器为每个函数生成的汇编代码段,从每个函数的代码段的调整栈顶指针语句中获得每个函数的栈帧的大小。
3.如权利要求1所述的基于编译过程中间结果的静态堆栈检测方法,其特征在于:
在所述步骤2)中,分析编译器为每个函数产生的RTL代码,寻找其中的调用指令,从而找到所有函数的调用关系。
4.如权利要求1所述的基于编译过程中间结果的静态堆栈检测方法,其特征在于:
在所述步骤3)中,函数调用关系图的定义如下:
函数调用关系图中的节点是程序中所有函数的集合,图中的边表示函数之间的调用关系,如果函数间存在调用关系,那么节点间通过有向弧相连接,这个有向弧从调用节点指向被调用节点,如果调用关系图中存在环,说明程序中存在递归调用。
5.如权利要求1所述的基于编译过程中间结果的静态堆栈检测方法,其特征在于所述步骤4)进一步包括以下步骤:
将图中所有的节点标记为未被访问的;
将图中所有的边标记为空;
堆栈大小初始化为零;
遍历函数调用关系图;
如果节点u正在被访问,则计算函数u使用的堆栈大小并加到总的堆栈大小中;
如果总的堆栈大小大于预设的堆栈最大值,则堆栈溢出;
如果节点u的邻居节点v被访问过了且v不是u的祖先节点则表明存在环;
如果节点v未被访问,则将u标记为v的祖先节点,然后以v为参数继续调用遍历函数;
通过该遍历算法并结合堆栈计算方法计算出堆栈使用的大小。
CN2010105398604A 2010-11-09 2010-11-09 基于编译过程中间结果的静态堆栈检测方法 Pending CN102012833A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN2010105398604A CN102012833A (zh) 2010-11-09 2010-11-09 基于编译过程中间结果的静态堆栈检测方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN2010105398604A CN102012833A (zh) 2010-11-09 2010-11-09 基于编译过程中间结果的静态堆栈检测方法

Publications (1)

Publication Number Publication Date
CN102012833A true CN102012833A (zh) 2011-04-13

Family

ID=43843009

Family Applications (1)

Application Number Title Priority Date Filing Date
CN2010105398604A Pending CN102012833A (zh) 2010-11-09 2010-11-09 基于编译过程中间结果的静态堆栈检测方法

Country Status (1)

Country Link
CN (1) CN102012833A (zh)

Cited By (14)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103744678A (zh) * 2014-01-14 2014-04-23 清华大学 基于寄存器传输语言确定静态函数调用关系的方法
CN104317773A (zh) * 2014-10-28 2015-01-28 南京大学 一种递归最大执行频度与深度的静态估计方法
CN104572094A (zh) * 2014-12-25 2015-04-29 上海斐讯数据通信技术有限公司 一种分析函数栈大小的方法
CN105468508A (zh) * 2014-09-04 2016-04-06 阿里巴巴集团控股有限公司 代码检测方法及装置
CN106250231A (zh) * 2016-03-31 2016-12-21 物联智慧科技(深圳)有限公司 计算堆栈大小的计算系统及方法
CN106547520A (zh) * 2015-09-16 2017-03-29 腾讯科技(深圳)有限公司 一种代码路径分析方法及装置
WO2017128952A1 (zh) * 2016-01-28 2017-08-03 中兴通讯股份有限公司 堆栈的保护方法及装置
CN107506299A (zh) * 2017-08-09 2017-12-22 平安科技(深圳)有限公司 一种代码分析方法及终端设备
CN109542942A (zh) * 2018-11-28 2019-03-29 网易(杭州)网络有限公司 函数调用的查询方法及装置、电子设备
CN110084042A (zh) * 2019-05-11 2019-08-02 肖银皓 一种应用程序堆栈静态分析方法及系统
CN112445482A (zh) * 2019-08-27 2021-03-05 无锡江南计算技术研究所 面向容量受限的程序栈空间深度追溯方法
CN113312054A (zh) * 2021-05-27 2021-08-27 长沙海格北斗信息技术有限公司 针对嵌入式软件架构的软件栈消耗分析方法及分析装置
CN114968417A (zh) * 2021-02-25 2022-08-30 中移物联网有限公司 一种函数调用方法、装置及设备
CN115268936A (zh) * 2022-09-27 2022-11-01 之江实验室 一种用于计算图编译的优化方法及装置

Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101271408A (zh) * 2008-05-07 2008-09-24 浙江大学 在嵌入式系统中分析堆栈使用的方法
CN101876923A (zh) * 2009-11-27 2010-11-03 中国科学院声学研究所 一种用于精确估计嵌入式系统中堆栈需求量的方法

Patent Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101271408A (zh) * 2008-05-07 2008-09-24 浙江大学 在嵌入式系统中分析堆栈使用的方法
CN101876923A (zh) * 2009-11-27 2010-11-03 中国科学院声学研究所 一种用于精确估计嵌入式系统中堆栈需求量的方法

Non-Patent Citations (2)

* Cited by examiner, † Cited by third party
Title
杨礼波等: "在堆栈缓冲区溢出中程序调用的分析和研究", 《电脑知识与技术》 *
潘超: "嵌入式软件的C语言代码静态检查技术研究", 《中国优秀硕士学位论文全文数据库》 *

Cited By (24)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103744678B (zh) * 2014-01-14 2017-05-03 清华大学 基于寄存器传输语言确定静态函数调用关系的方法
CN103744678A (zh) * 2014-01-14 2014-04-23 清华大学 基于寄存器传输语言确定静态函数调用关系的方法
CN105468508B (zh) * 2014-09-04 2018-07-03 阿里巴巴集团控股有限公司 代码检测方法及装置
CN105468508A (zh) * 2014-09-04 2016-04-06 阿里巴巴集团控股有限公司 代码检测方法及装置
CN104317773A (zh) * 2014-10-28 2015-01-28 南京大学 一种递归最大执行频度与深度的静态估计方法
CN104317773B (zh) * 2014-10-28 2017-05-24 南京大学 一种递归最大执行频度与深度的静态估计方法
CN104572094A (zh) * 2014-12-25 2015-04-29 上海斐讯数据通信技术有限公司 一种分析函数栈大小的方法
CN104572094B (zh) * 2014-12-25 2017-09-19 上海斐讯数据通信技术有限公司 一种分析函数栈大小的方法
CN106547520A (zh) * 2015-09-16 2017-03-29 腾讯科技(深圳)有限公司 一种代码路径分析方法及装置
CN106547520B (zh) * 2015-09-16 2021-05-28 腾讯科技(深圳)有限公司 一种代码路径分析方法及装置
WO2017128952A1 (zh) * 2016-01-28 2017-08-03 中兴通讯股份有限公司 堆栈的保护方法及装置
CN107015904A (zh) * 2016-01-28 2017-08-04 中兴通讯股份有限公司 堆栈的保护方法及装置
CN107015904B (zh) * 2016-01-28 2022-04-19 中兴通讯股份有限公司 堆栈的保护方法及装置
CN106250231A (zh) * 2016-03-31 2016-12-21 物联智慧科技(深圳)有限公司 计算堆栈大小的计算系统及方法
CN107506299A (zh) * 2017-08-09 2017-12-22 平安科技(深圳)有限公司 一种代码分析方法及终端设备
CN109542942B (zh) * 2018-11-28 2021-09-24 网易(杭州)网络有限公司 函数调用的查询方法及装置、电子设备
CN109542942A (zh) * 2018-11-28 2019-03-29 网易(杭州)网络有限公司 函数调用的查询方法及装置、电子设备
CN110084042A (zh) * 2019-05-11 2019-08-02 肖银皓 一种应用程序堆栈静态分析方法及系统
CN112445482A (zh) * 2019-08-27 2021-03-05 无锡江南计算技术研究所 面向容量受限的程序栈空间深度追溯方法
CN112445482B (zh) * 2019-08-27 2022-11-15 无锡江南计算技术研究所 面向容量受限的程序栈空间深度追溯方法
CN114968417A (zh) * 2021-02-25 2022-08-30 中移物联网有限公司 一种函数调用方法、装置及设备
CN113312054A (zh) * 2021-05-27 2021-08-27 长沙海格北斗信息技术有限公司 针对嵌入式软件架构的软件栈消耗分析方法及分析装置
CN115268936B (zh) * 2022-09-27 2022-12-27 之江实验室 一种用于计算图编译的优化方法及装置
CN115268936A (zh) * 2022-09-27 2022-11-01 之江实验室 一种用于计算图编译的优化方法及装置

Similar Documents

Publication Publication Date Title
CN102012833A (zh) 基于编译过程中间结果的静态堆栈检测方法
US9563487B2 (en) Runtime system
CN103136107A (zh) 一种嵌入式程序动态分配内存的变量调试方法
US9753705B2 (en) Conditional compilation of bytecode
CN114841326B (zh) 深度学习框架的算子处理方法、装置、设备和存储介质
CN109976760A (zh) 一种图形语言的交叉编译方法及交叉编译器
CN103294598A (zh) 一种源代码检查方法及装置
CN105808438B (zh) 一种基于函数调用路径的测试用例复用方法
CN104965687A (zh) 基于指令集生成的大数据处理方法及装置
CN109460237A (zh) 代码的编译方法及装置
US10303468B2 (en) Real-time quality of service monitoring apparatus and method
Li et al. MeterPU: a generic measurement abstraction API: Enabling energy-tuned skeleton backend selection
Carlsson et al. Worst-case execution time analysis of disable interrupt regions in a commercial real-time operating system
Tanaka et al. mruby--Rapid Software Development for Embedded Systems
CN102023923B (zh) 一种基于别名分析技术的软件测试方法
CN102662829B (zh) 一种复杂数据结构在代码静态测试中的处理方法和装置
CN105867886A (zh) 一种写表格的方法及装置
US20230116546A1 (en) Method for compilation, electronic device and storage medium
CN110704193A (zh) 一种适合向量处理的多核软件架构的实现方法及装置
CN109582300A (zh) 基于路径的代码变更分析方法、装置及设备
US20220198112A1 (en) Method, device, and storage medium for simulating a design
CN112100059B (zh) 一种c语言的指针类型分析方法
US20180285361A1 (en) Ranking service implementations for a service interface
Feeley Compiling for multi-language task migration
Cameron et al. A virtual machine for the Insense language

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C02 Deemed withdrawal of patent application after publication (patent law 2001)
WD01 Invention patent application deemed withdrawn after publication

Application publication date: 20110413