现在的位置: 首页 > 综合 > 正文

《WINDOWS核心编程第5版》随笔记录23

2018年02月07日 ⁄ 综合 ⁄ 共 6058字 ⁄ 字号 评论关闭

条目1、促使微软将SEH加入WINDOWS系统的因素之一是它可以简化操作系统本身的开发工作。(P621)

 

条目2、终止处理的语法(P622)

操作系统和编译器协同工作保证不管被保护的代码如何退出(return、goto、longjmp)的,终止处理程序都会被调用。即__finally代码块都能执行。(P622)

 

条目3、局部展开就是为了在try代码块非正常离开前,能够执行finally块而所做的工作。(P624)

我们应该避免在try语句中使用能让try语句块提前结束(跳过)的语句,因为这样会损害应用程序的性能。代码控制流正常地离开try代码块进入finally代码块时,性能开销最小。

验证:

(1)    编写正常离开try块的示例代码

(2)    编译后,反汇编其内容

我们很清楚的看到,当控制流正常离开try进入finally时,整体编译出来的代码比较精简、流畅,性能开销小(00401055处直接调用finally中的代码)。

(3)    编写非正常离开try块的示例代码

(4)    编译后,反汇编其内容

当控制流非正常离开try进入finally时,系统进行局部展开(0040105F   call    __local_unwind4),经过层层处理后在内部执行finally代码块。很明显,此时性能开销比较大。

 

条目4、从WINDOWS VISTA系统开始,须显式地保护try/finally框架,以确保在异常抛出时,finally代码块会执行。(P625)

 

条目5、终止处理程序(finally)同样可以捕获setjmp/longjmp、break、continue、goto等语句。(P626)

示例代码:

结果是:14

 

条目6、在进程或线程被提前终止的情况下,系统没办法保证finally代码块会被执行。换句话说,在try块中调用ExitProcess或ExitThread将不会导致finally代码块的执行。一个线程或进程被其他程序调用TerminateThread或TerminateProcess终止时,也不会导致finally代码块的执行。(P627)

 

条目7、关键字__leave会导致代码执行控制流跳转到try块的结尾,使代码以正常的方式从try块进入finally块中。(P631)

 

条目8、总结引起finally块执行的三个原因:

(1)    从try块到finally块的正常代码控制流

(2)    局部展开(从try块中提前退出进入finally块,由goto/longjmp/continue/break/return等语句引起)

(3)    全局展开

注意:在WINDOWS VISTA系统上,全局展开在默认的情况下是不会被触发的,所以finally不会被执行。调用AbnormalTermination宏可以确定与当前finally块相关的try快是否提前退出。AbnormalTermination宏只能在finally块中被调用。

 

 

抱歉!评论已关闭.