九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

读windows核心编程,结构化异常部分,理解摘要

23:

结束处理程序:

 

__try{}

__finally{}块语句,能保证在运行完__try的语句后能调用__finally{}块中的语句,就算是提前的return,break,continue,goto, 内存访问违规等都可以保证,但是当调用ExitThreadExitProcess,将立即结束线程或进程,由于调用TerminateThreadTerminateProcess而结束线程或进程,不会执行__finally块中的代码.

但是在__try块过早退出时,会导致局部展开,影响效率,应该尽量放在外面.

当碰到一些的确需要在块内部使用return,可以先用__leave关键字代替,以直接从__try块转到__finally,并在最后调用return语句返回,这样避免了局部展开,提高了效率,但是额外的代价是需要加入一个表示函数成功完成的bool变量.

可以在__finally块中调用AbnormalTermination内部函数确定是否是非正常退出__try,发生局部展开和内存访问违规等都算在内,此时返回true,当自然进入__finally块时,此函数返回false.可以通过这种方式决定到底在__finally块中执行什么代码.不能在其它地方调用.

此结束处理程序的作用:

简化错误处理,提高程序可读性,使代码更容易维护,使用得当具有很小的系统开销.

 

24:

异常处理程序:

 

__try{}

__except(){}

__try块中使用return,break,continue,goto语句不会带来额外开销.

__try{}

__except(EXCEPTION_EXECUTE_HANDLER){}

发生异常时,执行完__except块中的代码后,从其后的下一条语句开始执行.

__try{}

__except(EXCEPTION_CONTINUE_EXCUTION){}

发生异常时,执行完__except块中的代码后,重新从导致异常的原指令开始执行.

__try{}

__except(EXCEPTION_CONTINUE_SEARCH){}

发生异常时,不执行__except块中的代码,直接查找上一个匹配的__except块执行.

可以在_except块中和条件中调用GetExceptionCode()函数来确定到底是什么异常,不能在其它地方调用.

 

当一个异常发生时,操作系统向引起异常的线程的栈里压入三个结构,

EXCEPTION_RECORD, EXCEPTION_POINTERS, CONTEXT ,其中EXCEPTION_POINTERS就是两个指针成员,指向压入栈中的其它两个成员, breakpadexinfo结构就是这个指针的类型.并且成员和含义完全一样.

 

GetExceptionInformation函数只能在异常过滤器中使用,也就是__except的条件中调用.块中都不能使用.但是可以想办法在异常过滤器中就将结果保存下来,放到以后使用.

 

软件异常:

可以由void RaiseException(

  DWORD dwExceptionCode,

  DWORD dwExceptionFlags,

  DWORD nNumberOfArguments,

  const ULONG_PTR* lpArguments

);

引发.但是dwExceptionCode要遵循winerror.h文件中定义的一样的规则.

第二参数为是否允许异常过滤器返回EXCEPTION_CONTINUE_EXCUTION的标志位,当设为0为允许,设为EXCEPTION_NONCONTINUABLE为不允许,当不允许的时候,异常过滤器返回EXCEPTION_CONTINUE_EXCUTION,会引发新的异常EXCEPTION_CONTINUE_EXCEPTION.

在异常的时候发生新的异常,旧的异常消息会保留在EXCEPTION_RECORDExceptionRecord链表中.

 

25:

未处理异常和c++异常

Windows内部启动线程的方式也使用了SHE框架,当一个线程发生异常的时候,首先通过UnhandledExceptionFilter(GetExceptionInformation())处理,默认方式为弹出熟悉的报错对话框,close后通过ExitProcess(GetExceptionCode())退出,debug即传递合适的参数CreateProcess开启新的调试进程来调试异常的程序.

通过以SEM_NOGPFAULTERRORBOX为参数调用SetErrorModel函数,可以防止显示异常消息框.通过对每个线程和主线程的try-except块包装,可以自己处理每一个异常.而不调用默认的UnhandledExceptionFilter.windows还提供SetUnhandledExceptionFilter函数来定义某个进程中所有的线程发生异常时调用的异常过滤器.此函数的参数为用户自定义的异常过滤器的指针.

VC,C++的异常实际用SHE来实现,并且SHEC++异常有更多功能,比如可以从一个硬件错误中恢复过来.可以在一个程序不同函数中同时使用两套异常系统,但是不能混合使用,也不能在一个函数中使用两套系统.

 

分类:  C++ 
标签:  C++  《Windows核心编程》  结构化异常 

Posted By 九天雁翎 at 九天雁翎的博客 on 2008年06月13日

前一篇: SelfExtractor自解压模块理解文档 后一篇: lua table输出函数(可以输出嵌套表格)