轻视WinXPe异常系统健壮性将命悬一线
【IT168 专稿】众所周知,嵌入式系统强调的是系统健壮性。但当尝试关闭、启动Windows XP Embedded或在Windows XP Embedded运行应用程序时,可能会遇到类似的错误消息:A fatal exception XY has occurred at xxxx:xxxxxxxx。类似的代码常常出现在如遇到对非法指令的访问,访问了无效的数据或代码,操作的权限级别无效等。虽然多数情况下异常是可恢复的,但有时也必须重新启动系统或关机,具体取决于异常的严重性。
异常处理对于Windows XP Embedded程序开发是极其重要的一环,异常处理的好坏直接关系到系统的健壮性和稳定度。因此,了解和熟悉Windows XP Embedded的异常处理机制对于开发人员来说是必不可少的。近期,我在一个Windows XP Embedded嵌入式项目中就体验到轻视异常处理的惨痛教训。因为异常没有处理好,后果是严重影响系统的健壮性。本文分享在此项目过程中对异常处理的一些经验总结。
1. 什么是Windows XPe异常
(1)什么是异常
在Windows XPe运行时常常会出现一些非正常的现象,这种情况称为运行错误。根据其性质可以分为错误和异常。一般来说,最常见的错误有程序进入死循环,内存泄漏等。这种情况下运行的程序本身无法解决,只能通过其它程序干预。而异常是由于CPU执行了某些指令引起的,是程序执行时遇到的非正常情况或意外行为。这种情况不像错误类那样,通常在程序运行时可以解决,由异常代码调整程序运行方向使程序仍可继续运行直至正常结束。
异常和中断的区别是中断可在任何时候发生,与CPU正在执行什么指令无关。中断主要由I/O设备、处理器时钟或定时器等硬件引发,可以被允许或取消。一般这些情况都可以引发异常:代码或调用的代码(如共享库)中有错误,操作系统资源不可用,公共语言运行库遇到意外情况(如无法验证代码)等等。还有常见的有数组下标越界,算法溢出,除数为零,无效参数等,内核也将系统服务视为异常。
当意外行为在Windows XPe中发生时,系统将创建一个异常对象并把它抛出给运行时系统(Runtime system),然后运行时系统跳入另一个动作,就是要找到一些代码来处理这个异常。运行时系统会向后搜寻调用堆栈,从错误发生的函数,一直到找到一个包括合适的异常处理器(Exception Handler)的函数。异常处理器的选择被叫做:捕获异常(Catch the exception)。
(2)什么是异常调用程序
Windows XPe异常处理器是处理中断的主要组件之一,异常调用处理也是用户程序最基本的一种执行流程,它的性能直接影响着整个系统的可靠性。简单地说,异常调用是把执行权重新由应用程序还给操作系统,因此操作系统内核需要捕捉所有的异常,当操作系统捕获到异常时,也就重新获得CPU。因此,异常调用程序就是能够让系统在出现异常的情况下恢复过来的程序。
在Windows XP Embedded体系结构上,异常的实现原理和Windows XP一样。当应用程序进行系统调用时,它直接调用的是CoreDLL.DLL中的一个(Wrapper)函数,CoreDLL.DLL会被Windows XPe的所有进程加载。当CoreDLL.DLL发起一个异常时,也叫做软件中断。内核会响应这个软件中断,这时应用程序进程就会被挂起,接下来内核会根据不同的异常中断系统调用,找到具体实现该系统调用的进程(也被叫做PSL,全称是Protected Server Library)。此进程可能是系统内核,也可能不是。如果不是系统内核,那么执行就再次跳转,把执行转到具体实现异常处理的进程去执行。最后,当异常调用处理结束后应用程序再从CoreDLL.DLL的调用处返回,然后继续执行。
(3)Windows XPe的异常类型
在Windows XPe平台按优先级可分为:复位(Reset)、数据访问中止(Data abort)、快速中断请求(FIQ)、外部中断请求(IRQ)、指令预取中止(Prefech abort)、软件中断(Software interrupt SWI)、未定义的指令(Undefined instruction)等。其中, Reset仅在复位时发生,其它几种都是在系统运行时发生。