所谓异常,即指令执行时,原计划的执行顺序必须改变。导致这种改变的原因包括:1,用户主动抛出异常 2. 指令运行时异常。
要进行异常处理,第一步就是捕获异常。谁来捕获,可能是:1.程序本身 2. 操作系统。如果程序不捕获,操作系统也不捕获,系统肯定就崩溃了。程序本身只能捕获用户主动抛出的异常。这种用户主动抛出的异常,实际上是程序员实现知道的,所以实现准备了捕获代码。前面文章中的setjumper/longjump其实就是这种机制。
操作系统如果提供异常捕获机制,但操作系统如何处理异常呢?当然操作系统会提供些确认处理函数,否则的话操作系统只有崩溃了。目前可以猜想操作系统的处理方式可能包括把程序给杀死,然后产生resetlog,或者告诉user,比如在windows操作系统上。 用户程序也可以注册异常处理函数,然后异常的处理就先交给程序本身了。实际上,C++的异常处理机制就是利用了异常函数处理注册机制。
为了让程序员更加轻松应对异常处理,直接自己却注册异常处理函数,就太直接面对操作系统了,必须对操作系统掌握很充分。VC++在最原始的异常处理函数内部做了二次抽象。同时,再提供编译器和程序语法的支持,程序员就不要care其背后的机制了。
总的来说,要实现一个异常处理的完美方案,以下几个部分,必须合理工作才行:
1. 程序语言,主要是为了方便程序员,简单几个指令搞定,不用care实现细节
2.操作系统,异常本身就是操作系统分内应该处理的事情
3.硬件,主要是CPU对栈的原生支持。
4,栈,由于异常发生时,需要知道谁来处理,怎么处理,以及历史的清理,stack trace的打印。而这些信息都包含在栈中。而且栈本来就天生给线程使用的,对于处理多任务也非常方便。