新闻中心

EEPW首页>嵌入式系统>设计应用> 嵌入式软件设计中查找缺陷的几个技巧

嵌入式软件设计中查找缺陷的几个技巧

作者: 时间:2008-04-06 来源:网络 收藏

本文引用地址://m.amcfsurvey.com/article/258085.htm有时候,采用堆栈深度分析过程可能是无法做到,或者是不实际的。如果无法得到运行时库或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()来读取传感器的原始数据。在处理过程中,该数据被乘上一个定标因子,并加上一个偏移量。处理是在该数据的一个临时副本上进行的,然后,该临时副本被写入共享变量。


评论


相关推荐

技术专区

关闭