windows 结构化异常处理包括了2个方面:终止处理和异常处理. 本文讨论终止处理

1.终止处理程序

基本语法:

__try

{

//可能会发生异常的代码部分

}

__finally

{

//终止处理

}

在这段代码中,在编译器和操作系统协同下,try中发生异常,return,goto等非强制退出(即ExitProcess,TermainateProcess等方式退出),

__finally中的代码都会执行.

测试代码:

int main()
{
    int b;
    char c = 'a';
    __try
    {
        b = 3 /(c-97);//除0异常
    }
    __finally
    {
        printf("finally\n");
    }    
    return 0;
}

结果:

此时还未输出,点击取消时将:

后来才发现将生成模式改为release就不会弹出系统提示而直接输出finally. 所以要很好的利用seh 应该采用release模式生成项目

将除0代码改为return语句结果是直接输出finally

 

 

2.异常处理程序

代码结构:

__try
{

}

__except( //filter code)

{

 

}

过滤code只可以是

EXCEPTION_EXECUTE_HANDLER  1    :开始进行全局展开,执行异常处理代码,完了后继续执行except的后续代码

EXCEPTION_CONTINUE_SEARCH 0    ; 寻找外面一层try代码块

EXCEPTION_CONTINUE_EXECUTION -1  ;继续执行导致异常的那条代码

 

全局展开:

测试代码:

// seh2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
void f1()
{
    int a;
    char b = 'a';

    __try
    {
        a = b / (b - 97);//2
              //不执行 } __finally { printf(
"f1\n");//4 } } int main() { __try { f1(); //1 printf("main's try\n"); } __except (EXCEPTION_EXECUTE_HANDLER)//3 { printf("main\n");//5 } printf("over"); //6 return 0; }

执行结果:

 

 代码中数字为序号. 即当子函数中发生异常时会向外寻找except, 如果异常过滤程序返回EXCEPTION_EXECUTE_HANDLER  则进行全局展开

回去执行完finally后再执行except的异常处理函数,最后执行except后面的代码

 

 

3.GetExceptionInformation

当异常发生时将对目标线程压入3个结构的地址:

EXCEPTION_RECORD, CONTEXT(线程上下文) , EXCEPTION_POINTERS

typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;

typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

(struct _EXCEPTION_POINTERS*) GetExceptionInformation()

可以获取这些参数. 该函数只能在异常过滤函数中使用.