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

时间:2022-11-08 07:58:58


    在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;

}

}