终于把《让程序在崩溃时体面的退出》这个系列的6篇文章全部发表出来了。
这6篇文章分别是:
《让程序在崩溃时体面的退出之Unhandled Exception》
《让程序在崩溃时体面的退出之CallStack》
《让程序在崩溃时体面的退出之Dump文件》
《让程序在崩溃时体面的退出之SEH》
《让程序在崩溃时体面的退出之SEH+Dump文件》
《让程序在崩溃时体面的退出之终极解决方案(SEH+Dump+Unhandled Exception Filter)》
WINCE-如何通过map文件定位异常地址
对这些东西的研究起始于项目中一个Prototype的开发。这个Prototype就是给我们的产品加上Log信息。既然是Log信息,那么在应用程序崩溃的时候也要记录发生了什么而导致程序崩溃,而且这个信息对于开发人员来说是非常重要的。为此,在网上搜索了大量的资料来看,英文的中文的,再加上MSDN和那本砖头书《Windows via C/C++》,总算是把Windows下软件开发中对致命异常的处理给搞清楚了。按照我以前的习惯,把学到的新知识从新梳理总结了一下,写成了这6篇系列文章。
现在文章发表完了,这篇文章只是一个总结,而不是终结。因为在学习和写文章的过程中,还有一些问题没有彻底搞明白,比如SEH中的EXCEPTION_CONTINUE_EXECUTION和SEH与C++中的EH的混合使用。
SEH中的EXCEPTION_CONTINUE_EXECUTION
不管是MSDN还是《Windows via C/C++》,对SEH中的EXCEPTION_CONTINUE_EXECUTION解释都一样:Exception is dismissed. Continue execution at the point where the exception occurred.。也就是说返回到出现异常的地方重新执行。而且《Windows via C/C++》还专门写了一个例子来说明。可是我按照书上的例子写出同样的代码,执行的结果却跟书上不一样:首先,代码执行结果并不是期望的那样;其次,出现异常的那行代码后面的代码并没有执行。在网上搜索了一通,得到的答案是:返回到出现异常的地方重新执行是返回到汇编指令的那个地方,而不是C++代码的那一行,如果这个指令用到了寄存器内的内容,那么由于寄存器内容没有被修改,所以执行结果依然是错的。但是这只是解释了第一问题,对于第二个问题依然没有答案。如果有时间的话,我会继续对这个问题进行研究。
SEH与C++中的EH的混合使用
SEH是结构化的,不支持面向对象。而C++中的try/catch又只能捕捉到预定义的异常。各有优缺点,要想捕捉到所有异常,就要2个都用。那么代码的可读性和可维护性就会很差。不过,有网友看到我的文章后告诉我了一篇文章的地址,那篇文章就是讲怎么样将SEH的异常转换成C++中的异常。这是一个非常好的方法。有空的话,我也会对这方面进行一下研究。
|