APP下载

VxWorks应用开发中的异常分析及处理方法

2017-08-16李跃鹏康婧婧张健王琪元

电脑知识与技术 2017年19期
关键词:函数调用堆栈内存

李跃鹏,康婧婧,张健,王琪元

(许继电气股份有限公司,河南许昌461000)

VxWorks应用开发中的异常分析及处理方法

李跃鹏,康婧婧,张健,王琪元

(许继电气股份有限公司,河南许昌461000)

在嵌入式实时软件开发过程中,通常会由于非法指针、代码段破坏、堆栈溢出、内存泄漏、任务死循环等原因导致系统异常,并且难以定位异常原因。文章基于嵌入式实时操作系统VxWorks,对开发过程中常见的异常进行分析,并给出了异常故障记录、异常定位以及异常解决等方法。

VxWorks;代码段破坏;堆栈溢出;故障记录;异常定位

1 背景

随着嵌入式实时操作系统在工业自动化、航天、军事、通信等领域的快速发展与普及,越来越多的项目采用VxWorks、QNX、Windows CE、嵌入式Linux等嵌入式实时操作系统[1]。同时由于硬件系统处理性能越来越强,嵌入式系统的软件规模与复杂性不断增大,嵌入式开发者受限于经验和技术的不足,在软件设计中不可避免地存在各种问题,如何能快速、正确的定位嵌入式软件的异常并正确处理,在软件开发过程中起着重要作用[2]。

通常嵌入式系统中存在非法指针、代码段破坏、堆栈溢出、内存泄漏、任务死循环等软件错误,并且有些缺陷和错误难以发现,一旦被触发很可能造成系统死机或复位[3,4]。本文主要针对目前在嵌入式领域广泛应用的VxWorks操作系统,讨论如何能够在VxWorks开发中快速对异常原因进行定位分析并正确处理。

2 代码段保护

正文内容。从实时性角度看,嵌入式操作系统不可能采用通用操作系统的虚拟内存管理机制,即一般没有段页式的虚拟内存管理,而是采用简单、快速的内存分配方案[5,6]。因为虚拟内存管理机制会导致不确定性的I/O阻塞时间,使得程序运行期间不可预期。VxWorks虽然使用MMU(Memory ManagementUnit)和页表,但其内存映射相对简单,虚拟地址等同于物理地址,这样就导致了VxWorks的内核同用户程序处于同一内存空间,系统中所有任务共享同一物理内存空间,也就是说一个任务可以访问任何的内存地址。一旦某一个任务中存在错误的指针操作,访问了系统代码、数据段或者自定义运行时段,就可能影响其他任务的运行,甚至破坏系统内核,导致系统崩溃,因此系统中重要内存进行保护至关重要,是保证一个嵌入式系统可靠性的方法。

VxWorks使用MMU不是提供虚拟地址和物理地址之间的灵活映射,更多是提供面向页的Cache机制和权限控制机制。因此可以利用MMU的页保护机制,对系统代码段或者自定义运行时代码段进行保护[15]。VxWorks中每一个虚拟页都可以有一个或多个状态,分别为有效/无效、可写、可读、执行、缓存/不缓存等。页状态可以用函数vmStateSet()实现[8]。在程序中如果存在自定义运行时系统,为了防止其他任务破坏该区域,可以在运行时运行前将对应页面设置为可读和执行,使别的任务不能重写该页面,具体方法如下所示:

同时,除了针对自定义内存改变页属性方法外,还可以在Kernel Configuration中添加INCLUDE_PROTECT_TEXT组件,VxWorks就会对系统内核代码以及内核组件进行写保护。添加INCLUDE_PROTECT_VEC_TABLE组件,则可以针对异常向量表进行写保护[7]。通过以上三种方法的组合使用,开发过程中基本实现了所有代码段的保护。

3 堆栈跟踪

异常处理过程中关键的是堆栈跟踪,即使用堆栈回溯的方法实现现场分析。堆栈跟踪同处理器类型密切相关,需要根据处理器定义的应用程序二进制接口(AB I-Application Binary Interface)规则进行分析,其中主要包括基本数据类型、通用寄存器使用、参数传递规则、堆栈使用规则。下面以QorIQ Power⁃PC处理器P1010为例进行说明,P1010为32位e500内核,有32个通用寄存器,其中R1寄存器为堆栈寄存器SP,LR寄存器为链接寄存器[10]。

3.1 PowerPC应用程序二进制接口

AB I接口规定了应用程序与操作系统、应用程序与库、应用程序的组成部分之间的底层接口,其目的是使不同编译器编译出来的二进制文件可以互相使用。堆栈的使用规则也由ABI定义,图1是PowerPC函数调用的堆栈组织结构[9]。

图1 PowerPC堆栈组织结构

图1中,Back chain为每个函数栈帧的最低地址,根据该Back chain可以找到上一级栈帧的起始位置。LR save word为该函数执行完,返回到上一级函数调用地址的下一条指令位置,得到该地址就可以找到函数调用地址,通过查找符号表就能得到该函数名称。SP为函数的堆栈指针。

3.2 函数调用规则

对任意目标二进制代码objdump反汇编,并结合ABI应用程序二进制接口分析,发现几乎所有的函数开头都有如下形式[11]:

在函数的结尾都有如下形式:

根据以上分析函数调用中存在明显的特征标志,只要在需要分析代码段的上下文搜索特征标志,就可以找到函数入口地址以及返回地址。函数的入口地址得到后,通过VxWorks提供的函数symFindByValue()获得函数的名称。具体的流程如图2所示。

根据流程图可以得到被调用函数的入口地址(LR-1)以及返回地址(PrevSP),再将返回地址带入流程图起始搜索位置进行搜索,可以得到调用函数的入口地址以及返回地址,依次进行迭代即可得到完整的函数调用链。

图2 堆栈跟踪分析流程

当系统出现异常时,根据异常中断服务程序中记录的当前堆栈指针,再根据图2的分析流程进行迭代分析,就可以对发生异常时的堆栈进行跟踪,获得发生异常位置前后的函数调用关系,对问题分析提供了更多的信息,方便了用户对问题的定位[12]。

4 故障记录与存储

4.1 故障记录

VxWorks 6.x提升了系统故障诊断与定位能力,提供了错误检测与报告工具(Error Detective and Reporting,简称为ED&R)[13],它能跟踪系统运行轨迹,在系统发生异常时,详细记录故障类型、故障位置、故障前后代码、关键寄存器值以及当前任务堆栈使用情况等,并将这些信息存储在内存高地址空间中,不过这些存储的信息在目标系统热重启时会丢失,如果保存的错误信息过多,ED&R会将最旧的信息覆盖掉。

错误检测和报告工具在集成开发环境Workbench下都是以组件的形式提供给用户,用户只需要在Kernel Configuration文件中添加INCLUDE_EDR_SHOW组件,在主机的shell环境下,使用函数edrShow即可查看异常故障记录。程序开发人员根据这些信息可以准确地查看系统中的漏洞,从而提高开发效率。

图3 edrShow显示故障记录

4.2 故障存储

系统使用错误检测与报告工具将故障信息记录在内存中,可以随时在串口打印查看故障信息,方便问题的查找,但是一旦处理器掉电或者系统发生故障看门狗复位系统,内存中的ED&R故障信息就会丢失。若能将ED&R故障信息进行存储保存,开发人员就可以随时获取并根据这些故障信息准确地定位系统中的异常代码。

在VxWorks中设备以文件的形式提供给用户操作,当打开设备时,就返回文件描述符[14]。VxWorks使用0、1、2三个文件描述符作为系统保留的标准输入、标准输出、标准错误输出,并在usrConfig.c中对这三个标准文件描述符进行初始化,将串口作为标准输入、标准输出、标准错误输出设备[15]。默认故障信息的输出是在串口打印,因此需要在任务中将标准输出、标准错误输出重定向到指定的存储文件上[12]。具体方法如下代码所示:

这样就可以将当前任务状态统计、内存使用统计、堆栈上下文、ED&R故障等这些重要的信息存储在FLASH中,具体路径为tffs0目录下的edr.log文件,这样就不用担心处理器掉电或者看门狗复位导致信息丢失,随时可以使用这些丰富的信息记录对异常进行定位。

5 结束语

本文针对嵌入式操作系统VxWorks介绍了若干在软件发中可能碰到的问题,分别对代码段保护给出实现方法,任务堆栈跟踪原理进行分析,以及异常发生时如何对故障进行记录和存储,以及ED&R故障信息的存储,既保证了系统的稳定运行,同时也帮助了开发人员快速定位故障、快速解决问题。

[1]张敏燕.基于嵌入式实时操作系统VxWorks平台的分析与研究[D].南京:南京理工大学,2007.

[2]房同忠,杨卉卉,张华年,等.基于VxWorks的异常问题分析及调试方法的研究[J].工业控制计算机,2012(6):23-24.

[3]汪庆发.DSP的程序异常检测技术研究[D].哈尔滨:哈尔滨工业大学,2010.

[4]朱雪梅.基于动态方法的嵌入式软件缺陷检测技术研究与实现[D].杭州:杭州电子科技大学,2014.

[5]路艳丽,雷英杰.Linux 2.6内存保护机制研究[J].航空计算技术,2006(3):56-59.

[6]陆超,朱贺飞,陈兆千,等.针对Linux操作系统的MMU设计[J].小型微型计算机系统,2007(4):738-741.

[7]肖楠,高德远,吴列治,等.基于VxWorks的PowerPC750 MMU初始化流程和内存保护策略分析[J].科学技术与工程, 2008(5):1177-1182.

[8]刘小军,李秀娟.嵌入式操作系统VxWorks的内存管理技术研究[J].电子科技,2008(6):62-65.

[9]Freescale Semiconductor,Inc.PowerPC™e500 Core Family Reference Manual,Rev.1[M].2005,4.

[10]朱剑锋,缪万胜,康介祥.基于堆栈回溯的异常处理[J].计算机工程与设计,2014(12):4176-4180.

[11]王泽民,芦东昕,谢鑫,等.基于VxWorks的异常处理的研究和实现[J].计算机工程,2005(13):90-92.

[12]边聚广,魏海光,许春雷.基于异常处理的控制系统软件故障定位方法[J].微处理机,2012(4):59-62,66.

[13]周洁,刘永阳,甘跃斌,等.基于VxWorks内存错误检测与内核核心转储分析与应用[J].现代计算机,2013(25):30-33.

[14]张敏燕.基于嵌入式实时操作系统VxWorks平台的分析与研究[D].南京:南京理工大学,2007.

[15]曹桂平.VxWorks设备驱动开发详解[M].北京:电子工业出版社,2011.

Abnormal Analysis and Processing Method in VxWorks Application Development

LI Yue-peng,KANG Jing-jing,ZHANG Jian,WANG Qi-yuan (XJ Electric Co.,Ltd.,Xuchang 461000,China)

In the development of embedded realtime application,there are many reasons of this such as invalid point,code seg⁃ment damage,stack overflow,memory leakage,dead loop task.If it happens,the system would be abnormal and very difficult to debug for developer.This paper analyzes the general exceptions lead to abnormity base on VxWorks and provides the exception fault logging,locate the faults,and abnormal solutions method.

VxWorks;code segment damage;stack overflow;fault logging;fault detection

TP316.2

A

1009-3044(2017)19-0199-03

2017-05-16

李跃鹏(1988—),男,河南许昌人,助理工程师,硕士,主要研究方向为特高压直流输电控制保护平台研发;康婧婧,助理工程师,硕士;张健,助理工程师,硕士;王琪元,助理工程师,硕士。

猜你喜欢

函数调用堆栈内存
基于C语言的数学菜单的设计与实现
“春夏秋冬”的内存
基于函数调用序列模式和函数调用图的程序缺陷检测方法*
嵌入式软件堆栈溢出的动态检测方案设计*
探讨C++编程中避免代码冗余的技巧
基于堆栈自编码降维的武器装备体系效能预测
Unity3D项目脚本优化分析与研究
基于内存的地理信息访问技术
一种用于分析MCS-51目标码堆栈深度的方法
上网本为什么只有1GB?