简记Windows结构化异常处理之“终止处理”

=============================================================

标题:简记Windows结构化异常处理之“终止处理”

备注:

日期:2011.3.19

姓名:朱铭雷

=============================================================

结构化异常处理(SEH),可以让代码的功能部分同异常处理或者资源回收部分分离开来,使功能部分的代码更清晰可读,同时让代码的健壮性更好。SEH包含两种结构,一种叫做“终止处理”,一种叫做“异常处理”。

       终止处理

       __try

{}

__finally

{}

通常在这种结构中,__try块中的代码为主要功能代码,__finally块中的代码回收资源或处理异常和错误。__finally块中的代码肯定会被执行(除非线程或进程被终止),即使__try块中的代码包含return,goto等语句,或者存在内存访问异常。

       “终止处理”结构示例1

BOOL ReadFileData()

{

       HANDLE hFile = INVALID_HANDLE_VALUE;

       PVOID pvBuf = NULL;

       BOOL bRet = FALSE;

 

       __try

       {

              hFile = CreateFile(_T("filedata.dat"), GENERIC_READ,

                     FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

              if (hFile == INVALID_HANDLE_VALUE)

                     __leave;

             

              const int PAGESIZE = 4096;

              pvBuf = VirtualAlloc(NULL, PAGESIZE, MEM_COMMIT, PAGE_READWRITE);

              if (pvBuf == NULL)

                     __leave;

 

              BOOL bOk = FALSE;

              DWORD dwNumberOfBytesRead = 0;

              bOk = ReadFile(hFile, pvBuf, PAGESIZE, &dwNumberOfBytesRead, NULL);

              if (!bOk)

                     __leave;

 

              bRet = TRUE;

       }

       __finally

       {

              if (pvBuf != NULL)

                     VirtualFree(pvBuf, 0, MEM_DECOMMIT | MEM_RELEASE);

              if (hFile != INVALID_HANDLE_VALUE)

                     CloseHandle(hFile);

       }

       return bRet;

}

       这段程序将资源回收,全部放在了__finally块,使程序更加整洁,可读性更好。__leave使控制流跳转到__try块结尾,然后正常进入__finally块,这样程序开销很小。

       “终止处理”结构示例2

DWORD ProcessData()

{

       DWORD dwTemp = 0;

       __try

       {

              WaitForSingleObject(g_hSem, INFINITE);

              dwTemp = FunA(g_dwProtectedData);

       }

       __finally

       {

              ReleaseSemaphore(g_hSem, 1, NULL);

       }

       return dwTemp;

}

       这段程序如果没有使用SEH结构,如果FunA函数中存在非法内存访问,Windows将弹出WER对话框。如果点击取消,进程终止,将导致信号量得不到释放,其他等待该信号量的线程很可能永远得不到时间片。

       通常不要在__try块中和__finally块中,使用return,goto,continue,break语句,这些语句会造成“提前退出”和“局部展开”,一是对性能有影响,二是有些语句可能得不到执行。

       “终止处理”结构示例3

DWORD ProcessData()

{

       DWORD dwTemp = 0;

       __try

       {

              WaitForSingleObject(g_hSem, INFINITE);

              dwTemp = FunA(g_dwProtectedData);

       }

       __finally

       {

              ReleaseSemaphore(g_hSem, 1, NULL);

              if (!AbnormalTermination())

              {

                     // 控制流从__try块正常退出,进入__finally

                     // 相关处理操作

              }

              else

              {

                     // 控制流从__try块异常跳出,进入__finally

                     // 相关处理操作

              }

       }

       return dwTemp;

}

       通过AbnormalTermination函数可以判断出,控制流是正常还是异常退出__try块的,该函数由编译器产生内联代码。异常退出包括__try块中的代码因含有return,goto,continue,break语句而“提前退出”造成“局部展开”,或者__try块中的代码存在非法内存访问,或者其他异常导致“全局展开”等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值