首页 | 资讯动态 | linux基础 | 系统管理 | 网络管理 | 编程开发 | linux数据库 | 服务器技术 | linux相关 | linux认证 | 嵌入式 | 下载中心 | 专题 | linux招聘 | HR | 镜像
OKLinux中文技术站
·设为首页
·加入收藏
·联系我们
系统管理: 中文环境 系统管理 桌面应用 内核技术 | Linux基础: 基础入门 安装配置 常用命令 经验技巧 软件应用 | Linux数据库: Mysql Postgre Oracle DB2 Sybase other
网络管理: 网络安全 网络应用 Linux服务器 环境配置 黑客安全 | 编程开发: PHP CC++ Python Perl Shell 嵌入式开发 java jsp | PHP技术: PHP基础 PHP技巧 PHP应用 PHP文摘
搜索中心 Linux招聘 Linux专题 Apache | Linux相关: 硬件相关 Linux解决方案 Linux认证 企业应用 其它Unix | 相关下载: 资料下载 参考手册 开发工具 服务器类 软路由 其它
 技术搜索:
会员中心 注册会员 高级搜索  
  → 当前位置:首页>编程开发>嵌入式开发>正文

在嵌入式软件设计过程中查找缺陷的技巧

http://www.oklinux.cn  2007-08-23  赛迪网 kid  会员收藏  游客收藏  【 】 
您查看的文章来源于http://www.oklinux.cn

 

通常,每次一个函数被调用时,编译器将使用堆栈来保存返回地址并传递函数参数。函数的自动(局部)变量通常也在堆栈当中。不过,由于编译器会尽可能通过将参数或局部变量放入寄存器来优化代码,因此检查汇编语言以精确地确定堆栈用量非常重要。编译器也有可能在代码中的其它地方选择使用堆栈,如用堆栈来保存中间计算结果。

 

有些与编译器一起打包销售的开发环境包含生成调用树的工具,还有许多第三方的调用树生成工具。但是,除非它们能够对汇编语言进行分析,否则这些工具可能会遗漏运行时库和C库的调用。不过无论在哪种情况下,开发分析汇编语言文件并提取函数名称以及各函数内部调用的脚本都比较简单。分析的结果可写入一个文件,而这个文件能够方便地输入到表格之中。

 

确定了各个函数的堆栈用量之后,必须计算每个线程所需的最大堆栈数。由于一般程序通常涉及数百个函数,调用跨越多层深度,处理这些信息的一种简便方法就是采用分析表格。如表1所示,表格的各行包含了函数名称、该函数使用的最大堆栈数(包括调用其它函数所需的堆栈数),以及它调用的所有函数的清单。通过编程控制,这个表格从每个函数的"根"开始迭代循环,计算该函数及其调用的所有函数需要的堆栈。这些信息存放在堆栈路径列中,这样,采用每个线程根函数(如main)的堆栈路径数据就可以方便地计算出需要的最大堆栈数了。这个过程包含了先前介绍的堆栈分析过程中的前四个步骤。

 

有时候,采用堆栈深度分析过程可能是无法做到,或者是不实际的。如果无法得到运行时库或C库的源代码,而编译器厂商又没有提供任何堆栈使用信息,就不可能进行完整的堆栈分析。在这种情况下,有两种选择:

 

1. 在测试期间,观察堆栈所能达到的深度,并保证有较大的堆栈空间余量。

 

2. 检测堆栈溢出,并采取改进措施。

 

观察堆栈深度的方法很简单:

 

* 向整个内存堆栈区写入一个特定的数据图案符号,如55AA。

 

* 在预期使用最大堆栈空间的条件下运行系统。

 

* 使用仿真器或其它工具检查堆栈存储区,看有多少符号图案由于堆栈的使用而被改写了。

 

当然,这些步骤并不能保证在一些不同条件下不会需要更多的堆栈,但确实可以表明所需要的最小堆栈数。

 

使用带内存管理单元(MMU)的处理器时,有可能检测出运行时的堆栈溢出现象。MMU将内存划分为多个区域,用一个受保护的内存段来“警戒”堆栈区域。发生堆栈溢出时,处理器将访问这个受保护段。这个操作将引发一个异常事件(如产生SIGSEGV信号),可被程序捕获到。创建线程时,与实时POSIX标准兼容的RTOS提供有这种堆栈警戒功能选项,大大简化了编程人员的工作。GNU工具等其它开发环境包含有编译器开关,可在程序中添加实现堆栈警戒功能所需的代码,但它们仍然依靠底层操作系统来有效地处理堆栈溢出。但是,按照这种方式检测溢出还只是问题的一部分。为了使这类设计更为有效,系统必须能够从堆栈溢出中恢复过来并继续正确地工作。

 

在一个对安全或任务要求严格的应用中,系统运行时在测试或检测堆栈溢出期间监视堆栈的深度可能并不是一项足够的风险控制措施。对于一些应用,必须确保系统绝对不会越出所分配的堆栈范围;只有通过完整的堆栈深度分析才能证明这一点。这意味着,如果整个程序在同一内存空间运行,则必须对所有代码执行这项分析。不过,如果使用MMU,分析常可简化。在设计系统时,可将所有关键代码置于一个或多个独立线程内,而这些线程分别在各自的保护内存段中运行。这样,只要对这些关键线程进行堆栈使用分析就可以了。当然,这项简化设计假定当非关键线程溢出其堆栈并失效时,关键线程仍可正确执行。

 

由于分析工作所需的堆栈使用数据来自汇编语言清单,因此修改代码时,相应模块的堆栈使用信息必须予以更新。如果使用不同的编译器版本,或者改变了优化设置,也必须复核整个分析过程。在理想情况下,编译器将提供每个函数(如果不是每个线程的话)的堆栈使用数量,因为它拥有计算需要的所有信息。例如,瑞萨公司提供有Call Walker,这是该公司高性能的Embedded Workshop开发环境的一部分。这个工具可以图形化地显示每个函数使用的调用树和堆栈,包括运行时库和C库的函数。Call Walker也能找出使用堆栈数量最大的路径。使用这样的工具可以实现步骤1到步骤3的自动化。

 

竞争条件

 

当两个或更多独立线程同时访问同一资源时,就出现了竞争条件。竞争条件的影响多种多样,取决于具体的情况。清单1解释了一个潜在的竞争条件。函数Update_Sensor()通过调用get_raw()来读取传感器的原始数据。在处理过程中,该数据被乘上一个定标因子,并加上一个偏移量。处理是在该数据的一个临时副本上进行的,然后,该临时副本被写入共享变量。

 

如果在数据写入之前,使用shared_sensor的另一个线程或ISR先占(preempt)了这个线程,它将得到原来的传感器读数。使用临时副本可以防止先占线程读取只经过部分处理的数据。不过,如果这些代码在一个数据总线不足32位的处理器上运行,就会存在竞争条件。

 

在一个8位或16位的处理器上,向shared_sensor的写入操作并不是一次性完成的。在8位处理器上,写入32位浮点值可能需要四条指令,在16位处理器上可能需要两条指令。如果在对shared_sensor进行连续写入中途Update_Sensor()被先占,则先占线程将从由一部分老数据和一部分新数据组成的shared_sensor读取一个数值。根据应用的具体情况,这有可能造成严重的后果。解决的办法是锁定调度程序,或在更新共享变量期间禁止中断。

 

消除竞争条件通常很简单,但找出隐藏在代码中的竞争条件则需要仔细的分析。

 

对于由一个循环程序和不同ISR组成的简单系统,分析竞争条件很简单,只需检查每个ISR并识别它引用的所有共享变量。共享变量通常是这些系统中的全局数据,一旦这些共享变量被找出来之后,就可以检查它们在代码中的各次使用情况。每次访问都必须按需要进行保护,以避免潜在的冲突。在简单设计中,一般通过在关键代码段周围禁止中断来实现保护。遵守下列规则可帮助避免竞争问题:

 

* 如果一个ISR对共享数据进行写入,则该ISR之外的每次可中断的读操作都必须予以保护。

 

* 如果一个ISR对共享数据进行写入,则该ISR之外的任何读-修-写操作都必须予以保护。

 

* 如果一个ISR读取共享数据,则对该数据的可中断写操作必须予以保护。

 

* 如果一个ISR和其它代码都要检查一个硬件状态标志,以便在使用某资源之前确定其可用性,如:

共3页: 上一页 [1] 2 [3] 下一页

上一篇:当今常用的开源协议详细解析   下一篇:运行于Unix下非常优秀的Web服务器 Zeus

收藏于收藏夹】 【评论】 【推荐】 【打印】 【关闭
相关文档
·当今常用的开源协议详细解析
·嵌入式Linux系统中I/O端口需要注意的问题
·三种嵌入式操作系统的深入分析与详细比较
·几种Linux下嵌入式开发环境的简单介绍
·嵌入式系统的开发流程概括介绍
·在你的Ubuntu Linux桌面上嵌入终端窗口
·Linux嵌入应用之ARM体系结构的技术特征
·介绍嵌入式应用中存储器类型的选择技巧
·嵌入式系统开发学习如何起步、如何深入?
·嵌入式Linux系统的驱动程序开发要点
·Linux嵌入式系统的内存管理方法详细介绍
·Linux系统和嵌入式系统应用
·嵌入式Linux操作系统名词解释及资源大全
·用GNU工具开发基于ARM嵌入式系统的方法
· 2.6内核的Linux嵌入式系统应用
·嵌入式Linux系统的设计与应用
发表评论
密码: 匿名评论
评论内容:

(不超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规)
 
  最新文档
·“中立人士”对嵌入式Linux的相关评论
·嵌入式技巧:ARM的三种中断调试方法介
·嵌入式:关于Linux下_init与_exit的解
·在嵌入式Linux系统中应用的GTK 和X分析
·使用虚拟机嵌入式Linux开发前的必要准
·用NFS服务开发ARM Linux程序的方法介绍
·虚拟机Linux系统下连接ARM开发板的方法
·嵌入式Linux系统下的网页浏览器 WebKit
·系统学习嵌入式Linux 几点非常实用的建
·嵌入式Linux攻略 ACE程序移植过程详细
·嵌入式基础 当今常用的开源协议详细解
·Linux攻略 嵌入式系统的开发流程概括介
  阅读排行
· 常见的嵌入式操作系统都有哪些?
·嵌入式Linux文件系统详细介绍
·Linux攻略 嵌入式系统的开发流程概括介
·嵌入式Linux系统学习规划
·在嵌入式Linux系统中应用的GTK 和X分析
· 嵌入式linux下常见的文件系统
·系统学习嵌入式Linux 几点非常实用的建
· armlinux启动配置文件 /etc/init.d/rc
·嵌入式系统的开发流程概括介绍
·U-Boot的常用命令详解
·疯狂DIY! 在iPod上安装Linux系统
·嵌入式Linux系统下的网页浏览器 WebKit
·详述嵌入式系统下Microwindows的实现
·Linux嵌入式系统的内存管理方法详细介
·嵌入式Linux系统名词解释及资源大全
网摘收藏: