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\r\n",Sub1(x)); printf("%d\r\n",Sub1(NULL)); printf("%s\r\n", 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\r\n",Sub1(NULL)); //printf("%d\r\n",Sub1(NULL)); //printf("%s\r\n", 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\r\n",Sub1(NULL)); //printf("%d\r\n",Sub1(NULL)); //printf("%s\r\n", 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('\0'); } __except(EXCEPTION_CONTINUE_SEARCH ) { printf("EXCEPTION_CONTINUE_SEARCH\r\n");//無效的。 } } LONG Filter2(TCHAR **v1) { if (*v1 == NULL) { *v1 = BufferData; printf("EXCEPTION_CONTINUE_EXECUTION"); return(EXCEPTION_CONTINUE_EXECUTION); } return(EXCEPTION_EXECUTE_HANDLER); }