CN106294095A - 一种跟踪嵌入式系统函数调用轨迹的方法 - Google Patents
一种跟踪嵌入式系统函数调用轨迹的方法 Download PDFInfo
- Publication number
- CN106294095A CN106294095A CN201510241098.4A CN201510241098A CN106294095A CN 106294095 A CN106294095 A CN 106294095A CN 201510241098 A CN201510241098 A CN 201510241098A CN 106294095 A CN106294095 A CN 106294095A
- Authority
- CN
- China
- Prior art keywords
- function
- tracing
- embedded type
- type system
- track
- 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
Links
Abstract
本发明涉及一种开发人员追踪和定位系统异常的方法,尤其涉及一种跟踪嵌入式系统函数调用轨迹的方法。包括以下步骤:1)编译器分析程序代码,并向每个非内联的函数插入调用跟踪函数的代码;2)当函数被执行时调用跟踪函数,跟踪函数用于获取和保存当前函数的返回地址;3)直接输出各函数返回地址,或者通过调试工具将各函数返回地址解析转化为函数名字并输出。本发明的跟踪嵌入式系统函数调用轨迹的方法,回溯的实现方法较为简单且操控性较高、方便开发人员诊断。
Description
技术领域
本发明涉及一种开发人员追踪和定位系统异常的方法,尤其涉及一种跟踪嵌入式系统函数调用轨迹的方法。
背景技术
当嵌入式系统出现某些不可恢复或者致命的错误时,系统会崩溃,常称异常或者Trap,而此时的输出也称为Trap输出,通常包括异常类型、处理器当前运行环境(CPU各寄存器)、当前任务的栈内容、函数调用轨迹等,如Linux操作系统发生Oops时的输出。Trap输出是开发人员用于追踪和定位异常发生原因的必不可少的信息,尤其是函数调用轨迹用得最多,它能形象的反映出系统发生Trap时的函数执行顺序,甚至精确到触发Trap的函数名字,同时它相对其他输出也更易理解。
获取函数调用轨迹的方法,通常是通过扫描格式化的当前任务的栈帧,并从中提取出包含函数返回地址,以及上一个栈帧的地址等信息,然后逐层回溯直到结束。此方法比较通用,适用于大多数体系结构,但是其缺点也是明显的,主要在于当栈受到破坏时,是无法从中提取出函数调用轨迹的。比如软件实现是严重依赖处理器体系结构的,包括其各寄存器用途,指令集(ISA,InstructionSet Architecture)用法,函数调用的压栈、出栈方式,栈帧格式等,因此回溯的实现方法难度便大大增加了,也不容易维护、升级。
发明内容
为解决上述技术问题,本发明的目的是提供一种回溯的实现方法较为简单且操控性较高、方便开发人员诊断的跟踪嵌入式系统函数调用轨迹的方法。
本发明的一种跟踪嵌入式系统函数调用轨迹的方法,包括以下步骤:
1)编译器分析程序代码,并向每个非内联的函数插入调用跟踪函数的代码;
2)当函数被执行时调用跟踪函数,跟踪函数用于获取和保存当前函数的返回地址;
3)直接输出各函数返回地址,或者通过调试工具将各函数返回地址解析转化为函数名字并输出。
进一步的,步骤1)中调用跟踪函数的代码被插入在函数的函数体中语句部分之前。
进一步的,编译器内设置有编译选项,所述编译选项用于选择是否开启向每个非内联的函数插入调用跟踪函数的代码这一功能。
进一步的,步骤2)中跟踪函数将当前函数的返回地址保存为数组、链表或队列。
具体的,跟踪函数将当前函数的返回地址保存为数组。
具体的,跟踪函数保存当前函数的返回地址时,按顺序逐条由数组的头部至尾部循环记录在数组中。
具体的,连续相同的函数被执行时,跟踪函数仅保存一次该函数的返回地址。
借由上述方案,本发明至少具有以下优点:当发生异常时,可以提供开发人员详细明了的函数调用轨迹,回溯的实现方法较为简单且操控性较高,方便开发人员诊断。
上述说明仅是本发明技术方案的概述,为了能够更清楚了解本发明的技术手段,并可依照说明书的内容予以实施,以下以本发明的较佳实施例并配合附图详细说明如后。
附图说明
图1是本发明跟踪嵌入式系统函数调用轨迹的方法的流程图;
图2是本发明实施例中增加编译选项前的输出结果图;
图3是本发明实施例中增加编译选项后的输出结果图;
图4是本发明中解析函数返回地址并转化为函数名的输出结果图。
具体实施方式
下面结合附图和实施例,对本发明的具体实施方式作进一步详细描述。以下实施例用于说明本发明,但不用来限制本发明的范围。
实施例一
参见图1,本发明一较佳实施例所述的一种跟踪嵌入式系统函数调用轨迹的方法,包括以下步骤:
1)编译器分析程序代码,并向每个非内联的函数插入调用跟踪函数的代码;由于插入了代码,使用该功能后,函数的代码和占用的空间都变大了,同时多了一个函数调用的开销,甚至函数的运行时间也变长了,为了方便软件开发人员的使用,编译器内设置有编译选项,编译选项用于选择是否开启向每个非内联的函数插入调用跟踪函数的代码这一功能,换言之,这一功能可以选择性的打开和关闭,比如可以在Debug版本打开,在Release版本关闭;在调试Trap时打开,在调试完后关闭。
本步骤需要对编译器进行开发以提供支持,以提供一个编译选项,比如当开启时,向编译器增加选项-DEBUG:stack_check=4,此时编译器会向每个非内联的函数中插入一条指令,该指令会调用并跳转到一个跟踪函数,如__stackcheck。
应当说明的是,选项-DEBUG:stack_check=4只是编译选项的一种,本发明仅以选项-DEBUG:stack_check=4为例进行说明,凡是能够实现步骤1)中选择是否开启向每个非内联的函数插入调用跟踪函数的代码这一功能的编译选项,均应落入本发明的保护范围。
例如下面的Test_Func函数,在打开该选项后,其函数体多了调用__stackcheck的指令(如图2和图3所示),当然也多了为了调用函数__stackcheck而压栈、出栈等动作。
应当说明的是,__stackcheck只是跟踪函数的一种,本发明仅以__stackcheck为例进行说明,凡是能够实现步骤2)中跟踪函数功能的函数,均应落入本发明的保护范围。
2)当函数被执行时调用跟踪函数,跟踪函数用于获取和保存当前函数的返回地址(Return Address,RA);步骤1)中调用跟踪函数的代码被插入在函数的函数体中语句部分之前。
2.1在跟踪函数中获取函数返回地址
相对于现有技术中常见获取函数调用轨迹的方法,其过分依赖CPU体系结构,本方法只有在跟踪函数__stackcheck中去获取函数返回地址时,才依赖CPU体系结构。例如在本发明的验证体系结构中,使用以下的内联汇编来获得RA寄存器值。
RA寄存器中存放的是跟踪函数__stackcheck退出后,返回到的地址,通常是调用跟踪函数__stackcheck指令的下一条指令地址,例如在图3中,是0x60011194地址,当__stackcheck运行结束,将RA值赋值给程序计数器PC,则函数__stackcheck返回。
2.2在跟踪函数中保存函数返回地址
获得函数返回地址后,需要将其保存到一块预先开辟的空间,如数组、链表、或者队列,本发明中,仅以数组为例详细说明,链表和队列的方式,本发明不再赘述。
全局变量:
其中,
func_trace_disable:表示是否停止跟踪函数调用轨迹,默认为0;系统运行过程中可随时将其置1,停止跟踪,此时不会去获得和存储函数返回地址;重新置0表示继续跟踪。
header_idx:表示数组中最新记录应该存储到的位置下标。
FUNCTRACE_ITEMS_MAX:表示函数返回地址记录的最大条数。
func_trace_entry:表示函数返回地址记录的数组,能存储的最大条数为FUNCTRACE_ITEMS_MAX。
函数返回地址会按顺序逐条记录到数组中,越晚的记录代表越新的函数调用。由于数组的存储空间有限,而函数返回地址则是随着系统的运行,不断产生的;所以当记录条数大于FUNCTRACE_ITEMS_MAX时,会从数组头开始继续记录,换言之,先前记录在数组头的函数返回地址会被覆盖。
同时,为了节约有限的存储空间,连续相同的函数调用记录,只被存储一次。保存的过程如下:
3)直接输出各函数返回地址,或者通过调试工具将各函数返回地址解析转化为函数名字并输出。
换言之,对于跟踪函数调用轨迹的应用,可以存在以下方式:a)系统出现异常时,直接将各函数返回地址打印出来用于辅助调试;b)系统出现异常时,通过调试工具将各函数返回地址解析转化为函数名字,得到函数调用轨迹,打印出来用于辅助调试;c)系统正常运行时,调试工具也可以通过分析这些函数调用轨迹,辅助分析系统的运行状态。
根据步骤2)中记录存储的特性,先输出旧的记录,再输出新的记录,其中比header_idx越大的下标属于越旧的记录,并用0表示无效记录。输出过程如下:
通过工具链中的nm工具,将编译后生成的ELF文件中的符号的地址和名字映射表,解析出来,并通过相应的过滤、筛选,如图4所示,得到如下格式的输出:
函数起始地址+函数代码大小+类型+函数名字
所以,比RA寄存器值小的第一个函数起始地址,其对应的函数就是该RA记录对应的,被调用的函数名。比如在图4的例子中,RA记录值0x60011190表示函数Test_Func被调用,0x 600111c4表示函数Test_Func_C被调用。
实施例二
本发明还提供一个具体实施过程,如下所示:
现有如下代码,函数Test_Func_A调用Test_Func_B,Test_Func_B调用Test_Func_C,Test_Func_C调用Test_Func,Test_Func访问了非法地址0。
当系统运行到此段代码时,触发非法地址存取Trap并崩溃,打印如下函数调用轨迹输出:
对应的符号的地址和名字映射表如下,
由此可以发现,在调用完函数Test_Func后系统就发生了异常,再回去重新查看其代码,就容易定位错误了。
以上所述仅是本发明的优选实施方式,并不用于限制本发明,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明技术原理的前提下,还可以做出若干改进和变型,这些改进和变型也应视为本发明的保护范围。
Claims (7)
1.一种跟踪嵌入式系统函数调用轨迹的方法,其特征在于:包括以下步骤:
1)编译器分析程序代码,并向每个非内联的函数插入调用跟踪函数的代码;
2)当函数被执行时调用跟踪函数,跟踪函数用于获取和保存当前函数的返回地址;
3)直接输出各函数返回地址,或者通过调试工具将各函数返回地址解析转化为函数名字并输出。
2.根据权利要求1所述的跟踪嵌入式系统函数调用轨迹的方法,其特征在于:步骤1)中调用跟踪函数的代码被插入在函数的函数体中语句部分之前。
3.根据权利要求1所述的跟踪嵌入式系统函数调用轨迹的方法,其特征在于:编译器内设置有编译选项,所述编译选项用于选择是否开启向每个非内联的函数插入调用跟踪函数的代码这一功能。
4.根据权利要求1所述的跟踪嵌入式系统函数调用轨迹的方法,其特征在于:步骤2)中跟踪函数将当前函数的返回地址保存为数组、链表或队列。
5.根据权利要求4所述的跟踪嵌入式系统函数调用轨迹的方法,其特征在于:跟踪函数将当前函数的返回地址保存为数组。
6.根据权利要求5所述的跟踪嵌入式系统函数调用轨迹的方法,其特征在于:跟踪函数保存当前函数的返回地址时,按顺序逐条由数组的头部至尾部循环记录在数组中。
7.根据权利要求1所述的跟踪嵌入式系统函数调用轨迹的方法,其特征在于:连续相同的函数被执行时,跟踪函数仅保存一次该函数的返回地址。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510241098.4A CN106294095A (zh) | 2015-05-13 | 2015-05-13 | 一种跟踪嵌入式系统函数调用轨迹的方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510241098.4A CN106294095A (zh) | 2015-05-13 | 2015-05-13 | 一种跟踪嵌入式系统函数调用轨迹的方法 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN106294095A true CN106294095A (zh) | 2017-01-04 |
Family
ID=57631639
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201510241098.4A Pending CN106294095A (zh) | 2015-05-13 | 2015-05-13 | 一种跟踪嵌入式系统函数调用轨迹的方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN106294095A (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN106940681A (zh) * | 2017-03-11 | 2017-07-11 | 郑州云海信息技术有限公司 | 一种利用跟踪函数和解析工具调试存储软件的方法 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20110145800A1 (en) * | 2009-12-10 | 2011-06-16 | Microsoft Corporation | Building An Application Call Graph From Multiple Sources |
CN102109975A (zh) * | 2009-12-24 | 2011-06-29 | 华为技术有限公司 | 确定函数调用关系的方法、装置及系统 |
CN103106132A (zh) * | 2013-03-05 | 2013-05-15 | 中标软件有限公司 | Linux系统崩溃时内核函数调用栈分析调试方法 |
-
2015
- 2015-05-13 CN CN201510241098.4A patent/CN106294095A/zh active Pending
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20110145800A1 (en) * | 2009-12-10 | 2011-06-16 | Microsoft Corporation | Building An Application Call Graph From Multiple Sources |
CN102109975A (zh) * | 2009-12-24 | 2011-06-29 | 华为技术有限公司 | 确定函数调用关系的方法、装置及系统 |
CN103106132A (zh) * | 2013-03-05 | 2013-05-15 | 中标软件有限公司 | Linux系统崩溃时内核函数调用栈分析调试方法 |
Non-Patent Citations (3)
Title |
---|
LURAN82: "C语言的那些小秘密之函数的调用关系", 《百度文库:HTTPS://WENKU.BAIDU.COM/VIEW/58AEF7A70029BD64783E2C84.HTML?FROM=SEARCH》 * |
VU5611789: "嵌入式Linux应用程序调试方法", 《百度文库:HTTPS://WENKU.BAIDU.COM/VIEW/6E5B327D168884868762D643.HTML?FROM=SEARCH》 * |
向勇 等: "基于内核跟踪的动态函数调用图生成方法", 《计算机应用研究》 * |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN106940681A (zh) * | 2017-03-11 | 2017-07-11 | 郑州云海信息技术有限公司 | 一种利用跟踪函数和解析工具调试存储软件的方法 |
CN106940681B (zh) * | 2017-03-11 | 2020-07-21 | 苏州浪潮智能科技有限公司 | 一种利用跟踪函数和解析工具调试存储软件的方法 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US10372594B2 (en) | Method and device for retrieving test case based on code coverage | |
CN109313567B (zh) | 虚拟化精确的基于事件的采样的设备和方法 | |
Cabral et al. | Exception handling: A field study in java and. net | |
US7058927B2 (en) | Computer software run-time analysis systems and methods | |
JP5430570B2 (ja) | システムコールカバレッジ基準による試験スイート削減のための方法 | |
US8245194B2 (en) | Automatically generating unit test cases which can reproduce runtime problems | |
US20150234730A1 (en) | Systems and methods for performing software debugging | |
CN109491990A (zh) | 一种检测数据质量的方法以及检测数据质量的装置 | |
US20130132933A1 (en) | Automated compliance testing during application development | |
US8732681B2 (en) | Stack analysis for post mortem analysis | |
US8555234B2 (en) | Verification of soft error resilience | |
US20040054991A1 (en) | Debugging tool and method for tracking code execution paths | |
CN105022694B (zh) | 用于移动终端测试的测试用例生成方法及系统 | |
US20040153814A1 (en) | Apparatus and method for trace stream identification of a processor reset | |
JP6363152B2 (ja) | データフロー分析のための装置、方法、コンピュータプログラム及び記憶媒体 | |
CN106537351B (zh) | 用于诊断无线通信设备中的电源故障的方法 | |
CN113050953A (zh) | 基于注释生成代码的方法、装置及存储介质 | |
CN104252402A (zh) | 一种程序调试方法及装置 | |
US7069470B2 (en) | System and method for intelligent trap analysis | |
CN104461880B (zh) | 一种嵌入式系统中自动检测内存越界的方法及系统 | |
CN109426496A (zh) | 程序日志写入文件的方法、存储介质、电子设备及系统 | |
CN106294095A (zh) | 一种跟踪嵌入式系统函数调用轨迹的方法 | |
Mu et al. | Renn: Efficient reverse execution with neural-network-assisted alias analysis | |
US20080115016A1 (en) | System and method for analyzing unknown file format to perform software security test | |
KR100924519B1 (ko) | 소프트웨어 보안 테스팅을 수행하기 위한 알려지지 않은파일 포맷 분석 시스템 및 방법 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
RJ01 | Rejection of invention patent application after publication |
Application publication date: 20170104 |
|
RJ01 | Rejection of invention patent application after publication |