• 异常过滤程序 EXCEPTION_EXECUTE_HANDLER, EXCEPTION_CONTINUE_EXECUTION,EXCEPTION_CONTINUE_SEARCH


    EXCEPTION_EXECUTE_HANDLER (1) 异常已经被识别,也即当前的这个异常错误,系统已经找到了并能够确认,这个__except模块就是正确的异常处理模块。控制流将进入到__except模块中,当except代码块运行结束后,系统会认为异常已经处理,于是允许应用程序继续执行。

    全局展开 异常产生,系统夺回控制权,搜索与try块匹配的except块。因为F1中的try块匹配的是finally,于是系统调用栈中向上搜索到另一个try块,当异常过滤程序计算结果为EXCEPTION_EXECUTE_HANDLER,系统必须进行全局展开。马上在发生异常出的finally块中开始全局展开。寻找所有未完成的finally块的try块


    如果一个异常发生在try、finally块中,且在其上层没有try、except,进程立刻终止。即全局展开不会发送,finally块也不会执行。

    在finally中放入return可以阻止全局展开进行

    //以空格作为分割符的符号个数
    //内存复制功能
    // test1.cpp : 定义控制台应用程序的入口点。
    //
    #include <Windows.h>
    #include <tchar.h>
    #include <winternl.h>
    #include <Shlwapi.h>
    #include<iostream>
    
     
    
    int Sub1(const char* v1);
    CHAR* Sub2(CHAR*Source, size_t Destination);
    
     
    
    const char* x = "11 11 1 ssssssssssss";
    
     
    
    
    int main()
    {
    printf("%d
    ",Sub1(x));
    printf("%d
    ",Sub1(NULL));
    printf("%s
    ", Sub2("11 11 1 ssssssssssss",50));
    return 0;
    
    }
    
    int Sub1(const char* v1)
    {
    int length = -1;
    char* Buffer = NULL;
    __try
    {
    Buffer = (char*)malloc(strlen(v1) + 1);
    strcpy(Buffer, v1);
    char* pszToken = strtok(Buffer,"s");//在第一次调用 strtok 时,函数跳过前导分隔符(连在一起算一个)并返回指向在 strToken的第一个标记的指针,以空字符终止标记。 通过一系列 strtok 的调用,多个标记将被从 strToken 的其余部分拆开。 每个 strtok调用通过插入 null 字符在该调用返回 token 之后修改strToken。
    for (; pszToken != NULL; pszToken = strtok(NULL, "s"))
    length++;
    length++;
    
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    
    }
    free(Buffer);
    return(length);
    }
    CHAR* Sub2(CHAR*Source, size_t size)
    {
    CHAR* v1 = NULL;
    __try
    {
    v1 = (CHAR*)malloc(size);
    memcpy(v1, Source, size);
    
    
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    free(v1);
    
    v1 = NULL;
    }
    return(v1);
    }

    EXCEPTION_CONTINUE_EXECUTION (–1) 异常被忽略或已被修复,程序控制留跳转到导致异常的那条指令,并尝试重新执行这条指令,继续恢复运行。需要很谨慎

    //
    //
    // test1.cpp : 定义控制台应用程序的入口点。
    //
    #include <Windows.h>
    #include <tchar.h>
    #include <winternl.h>
    #include <Shlwapi.h>
    #include<iostream>
    
    TCHAR BufferData[100];
    
    int Sub1(const char* v1);
    CHAR* Sub2(CHAR*Source, size_t Destination);
    
    LONG Filter1(TCHAR **v1);
    
    void Sub5();
    const char* x = "11 11 1 ssssssssssss";
    
     
    
    
    int main()
    {
    Sub5();
    // printf("%d
    ",Sub1(NULL));
    //printf("%d
    ",Sub1(NULL));
    //printf("%s
    ", Sub2("11 11 1 ssssssssssss",50));
    return 0;
    
    }
    
    int Sub1(const char* v1)
    {
    int length = -1;
    char* Buffer = NULL;
    __try
    {
    Buffer = (char*)malloc(strlen(v1) + 1);
    strcpy(Buffer, v1);
    char* pszToken = strtok(Buffer,"s");//在第一次调用 strtok 时,函数跳过前导分隔符(连在一起算一个)并返回指向在 strToken的第一个标记的指针,以空字符终止标记。 通过一系列 strtok 的调用,多个标记将被从 strToken 的其余部分拆开。 每个 strtok调用通过插入 null 字符在该调用返回 token 之后修改strToken。
    for (; pszToken != NULL; pszToken = strtok(NULL, "s"))
    length++;
    length++;
    
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    
    }
    free(Buffer);
    return(length);
    }
    CHAR* Sub2(CHAR*Source, size_t size)
    {
    CHAR* v1 = NULL;
    __try
    {
    v1 = (CHAR*)malloc(size);
    memcpy(v1, Source, size);
    
    
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    free(v1);
    
    v1 = NULL;
    }
    return(v1);
    }
    
    void Sub5()
    {
    int v1 = 0;
    TCHAR *pBuffer = NULL;
    __try
    {
    *pBuffer = TEXT('j');//第一次 指针没有初始化 进Filter1()返回EXCEPTION_CONTINUE_EXECUTION 需要很谨慎
    v1 = 5 / v1;//第二次发生异常 v1初始化为0
    }
    __except(Filter1(&pBuffer))
    {
    
    MessageBox(NULL, NULL, NULL, MB_OK);
    }
    MessageBox(NULL,TEXT("ssss"), NULL, MB_OK);
    }
    
    LONG Filter1(TCHAR **v1)
    {
    if (*v1 == NULL)
    {
    *v1 = BufferData;
    printf("hello");
    return(EXCEPTION_CONTINUE_EXECUTION);
    }
    return(EXCEPTION_EXECUTE_HANDLER);
    }

    EXCEPTION_CONTINUE_SEARCH (0) 异常不被识别,也即当前的这个__except模块不是这个异常错误所对应的正确的异常处理模块。系统将继续到上一层的try-except域中继续查找一个恰当的__except模块。
    单纯返回常量EXCEPTION_CONTINUE_SEARCH,系统寻找到在它上一层的一个try块并调用对应的异常过滤程序中的函数。(此时若出现异常终止程序会先忽略)

    //以空格作为分割符的符号个数
    //内存复制功能
    // test1.cpp : 定义控制台应用程序的入口点。
    //
    #include <Windows.h>
    #include <tchar.h>
    #include <winternl.h>
    #include <Shlwapi.h>
    #include<iostream>
    
    TCHAR BufferData[100];
    
    
    void Sub6();
    void Sub6_BELONG(TCHAR *v1);
    LONG Filter2(TCHAR **v1);
    int main()
    {
    Sub6();
    //Sub5();
    // printf("%d
    ",Sub1(NULL));
    //printf("%d
    ",Sub1(NULL));
    //printf("%s
    ", Sub2("11 11 1 ssssssssssss",50));
    return 0;
    
    }
    void Sub6()
    {
    TCHAR *pBuffer = NULL;
    __try
    {
    Sub6_BELONG(pBuffer);
    }
    __except(Filter2(&pBuffer))
    {
    
    MessageBox(NULL, NULL, NULL, MB_OK);
    }
    }
    void Sub6_BELONG(TCHAR *v1)
    {
    
    __try
    {
    *v1 = TEXT('');
    }
    __except(EXCEPTION_CONTINUE_SEARCH )
    {
    
    printf("EXCEPTION_CONTINUE_SEARCH
    ");//无效的。
    }
    
    }
    LONG Filter2(TCHAR **v1)
    {
    if (*v1 == NULL)
    {
    *v1 = BufferData;
    printf("EXCEPTION_CONTINUE_EXECUTION");
    return(EXCEPTION_CONTINUE_EXECUTION);
    }
    return(EXCEPTION_EXECUTE_HANDLER);
    }
  • 相关阅读:
    BZOJ3790 神奇项链
    Tarjan求Lca
    Manacher算法--Poj3974
    [Usaco2015 Feb]Censoring
    扩展Kmp
    Ural1297 最长回文串
    [Usaco2007 Dec] 队列变换
    Pku2774 最长公共子串
    Spoj 694 Distinct Substrings
    Pku1734 Musical Theme 不可重叠最长重复子
  • 原文地址:https://www.cnblogs.com/Crisczy/p/7728937.html
Copyright © 2020-2023  润新知