天天看点

windows SEH机制注释(2) 基于ReactOS

    在windows SEH机制注释(1) 基于ReactOS 一文中,注释了try/except宏,windows的SEH机制除了这对宏,还有try/finall宏,用来执行善后处理。相比try/except,try/finall简单很多,没有绕人的长跳转,基本上属于顺序处理流程。如下:

1.
func()
{
     _SEH_TRY

     {

         //do sth

         _asm int 0x03;

     }

     _SEH_FINALLY(FINALLY_)

     {

         status = _SEH_GetExceptionCode();

     }

     _SEH_END

 }      

2.宏扩展

func()

 {

     for(;;) 

     { 

         _SEH_INIT_CONST int _SEHTopTryLevel = (_SEHScopeKind != 0); 

         _SEHPortableFrame_t * const _SEHCurPortableFrame = _SEHPortableFrame; 

         _SEHPortableTryLevel_t * const _SEHPrevPortableTryLevel = _SEHPortableTryLevel; 

      

         { 

             _SEH_INIT_CONST int _SEHScopeKind = 0; 

             register int _SEHState = 0; 

             register int _SEHHandle = 0; 

             _SEHFrame_t _SEHFrame; 

             _SEHTryLevel_t _SEHTryLevel; 

             _SEHPortableFrame_t * const _SEHPortableFrame = 

                 _SEHTopTryLevel ? &_SEHFrame.SEH_Header : _SEHCurPortableFrame; 

             _SEHPortableTryLevel_t * const _SEHPortableTryLevel = &_SEHTryLevel.ST_Header; 

     

             (void)_SEHScopeKind; 

             (void)_SEHPortableFrame; 

             (void)_SEHPortableTryLevel; 

             (void)_SEHHandle; 

     

             for(;;) 

             { 

                 if(_SEHState)

                 /*

                 初始时_SEHState为0,进入SEH_FINALL!else分支,设置SEH处理结构__SEHTryLevel

                 */ 

                 { 

                     for(;;) 

                     { 

                         {

                     <-try/

                         {

                                 //(1)

                            //do sth,如果发生异常,没有跳转,确切的说是由系统在fs:[0]中查找上一层堆栈中提供的处理函数
                           //如果没有发生异常,顺序的执行到(2)处,执行善后处理
                             _asm int 0x03;

                         }

                       finall ->/

                        } 

     

                         break; 

                     } 

     

                     _SEHPortableFrame->SPF_TopTryLevel = _SEHPrevPortableTryLevel; 

                     break; 

                 } 

                 else 

                 { 

                     _SEHTryLevel.ST_Header.SPT_Handlers.SH_Filter = 0; 

                     /*

                     FINALLY_由_SEH_FINALLY(FINALLY_)传入,设置收尾函数

                     */

                     _SEHTryLevel.ST_Header.SPT_Handlers.SH_Finally = (FINALLY_); 

     

                     _SEHTryLevel.ST_Header.SPT_Next = _SEHPrevPortableTryLevel; 

                     _SEHFrame.SEH_Header.SPF_TopTryLevel = &_SEHTryLevel.ST_Header; 

     

                     if(_SEHTopTryLevel) 

                     { 

                         if(&_SEHLocals != _SEHDummyLocals) 

                             _SEHFrame.SEH_Locals = &_SEHLocals; 

     

                         _SEH_EnableTracing(_SEH_DO_DEFAULT_TRACING); 

                         _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; 

                         _SEHEnterFrame(&_SEHFrame.SEH_Header); 

                     } 

                     /*

                     经过++ _SEHState; 

                     continue;

                     程序进入if(_SEHState),执行受保护的代码(其实不算受保护的代码,与

                     SEH_Except相比少了长跳转)

                     */

                     ++ _SEHState; 

                     continue; 

                 } 

                 //(2)

                 break; 

             } 

             // _SEH_FINALLY(FINALLY_)

             /*

             执行这个回调有2种可能

             1.执行完(1)后,一路break出来,执行善后函数或者

             2.执行(1)时遇到异常,进入异常处理过程。期间执行unwind时会调用

             (SEHTryLevel.ST_Header.SPT_Handlers.SH_Finally)(&_SEHFrame.SEH_Header);

             */

             (FINALLY_)(&_SEHFrame.SEH_Header); 

     

             if(0) 

             {

     //

                         {

                             status = _SEH_GetExceptionCode();

                         }

         //

         } 

         } 

     

         if(_SEHTopTryLevel) 

             _SEHLeaveFrame(); 

     

         break; 

     }

 }      

继续阅读