青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 311, comments - 0, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

一、   綜述

SEH--Structured Exception Handling,是Windows操作系統(tǒng)使用的異常處理方式。

對于SEH,有點需要說明的是,SEH是屬于操作系統(tǒng)的特性,不為特定語言設(shè)計,但是實際上,作為操作系統(tǒng)的特性,幾乎就等同與面向C語言設(shè)計,這點很好理解,就像Win32 API,Linux下的系統(tǒng)調(diào)用,都是操作系統(tǒng)的特性吧,實際還是為C做的。但是,作為為C語言設(shè)計的東西,實際上可調(diào)用的方式又多了,匯編,C++對于調(diào)用C語言的接口都是比較方便的。

 

二、   基礎(chǔ)篇

還是簡單介紹一下SEH的使用,但是不準備太詳細的介紹了,具體的詳細介紹見參考中提及的書目。關(guān)于SEH的基本應(yīng)用,Windows核心編程》絕對是最佳讀物(其實個人一直認為《Windows核心編程》是Windows編程領(lǐng)域必看的第二本書,第一本是《Programming Windows》。關(guān)于SEH更深入的一點的知識可能就要參考一些能用匯編講解的書籍了,《Windows用戶態(tài)程序高效排錯》算是其中講的不錯的一本。

首先,SEH也有像C++異常一樣的語法,及類try-catch語法,在SEH中為__try-except語法,拋出異常從throw改為RaiseException,MSDN中的語法描述為:

__try 

{

   // guarded code

}

__except ( expression )

{

   // exception handler code

}

 

見一個實際使用的例子:

1

#include <iostream>

#include <windows.h>

using namespace std;

 

int main()

{

    __try

    {

       RaiseException(0, 0, 0, NULL);

    }

    __except(EXCEPTION_EXECUTE_HANDLER)

    {

       cout <<"Exception Raised." <<endl;

 

    }

 

    cout <<"Continue running" <<endl;

}

 

這可能是最簡單的SEH的例子了,輸出如下:

Exception Raised.

Continue running

 

這個例子和普通C++異常的try-catch類似,也很好理解。只不過catch換成了except

因為C語言沒有智能指針,那么就不能缺少finally的異常語法,與JAVA,Python等語言中的也類似,(這是C++中沒有的)finally語法的含義就是無論如何(不管是正常還是異常),此句總是會執(zhí)行,常用于資源釋放。

 

2

 

#include <iostream>

#include <windows.h>

using namespace std;

 

int main()

{

    __try

    {

 

       __try

       {

           RaiseException(0, 0, 0, NULL);

       }

       __finally

       {

           cout <<"finally here." <<endl;

 

       }

    }

    __except(1)

    {

 

    }

 

    __try

    {

 

       __try

       {

           int i;

       }

       __finally

       {

           cout <<"finally here." <<endl;

 

       }

    }

    __except(1)

    {

 

    }

    cout <<"Continue running" <<endl;

    getchar();

}

 

這個實例看起來過于奇怪,因為沒有將各個try-finally放入獨立的模塊之中,但是說明了問題:

1.     finally的語句總是會執(zhí)行,無論是否異常finally here總是會輸出。

2.     finally僅僅是一條保證finally語句執(zhí)行的塊,并不是異常處理的handle語句(與except不同),所以,假如光是有finally語句塊的話,實際效果就是異常會繼續(xù)向上拋出。(異常處理過程也還是繼續(xù))

3.     finally執(zhí)行后還可以用except繼續(xù)處理異常,但是SEH奇怪的語法在于finallyexcept無法同時使用,不然會報編譯錯誤。

如下例:

    __try

    {

       RaiseException(0, 0, 0, NULL);

    }

    __except(1)

    {

 

    }

    __finally

    {

       cout <<"finally here." <<endl;

 

    }

 

VS2005會報告

error C3274: __finally 沒有匹配的try

這點其實很奇怪,難道因為SEH設(shè)計過于老了?-_-!因為在現(xiàn)在的語言中finally都是允許與except(或類似的塊,比如catch)同時使用的。C#JAVA,Python都是如此,甚至在MSC++做的托管擴展中都是允許的。如下例:(來自MSDN中對finally keyword [C++]的描述)

using namespace System;

 

ref class MyExceptionpublic System::Exception{};

 

void ThrowMyException() {

    throw gcnew MyException;

}

 

int main() {

    try {

       ThrowMyException();

    }

    catch ( MyExceptione ) {

       Console::WriteLine(  "in catch" );

       Console::WriteLinee->GetType() );

    }

    finally {

       Console::WriteLine(  "in finally" );

    }

}

 

當你不習(xí)慣使用智能指針的時候常常會覺得這樣會很好用。關(guān)于finally異常語法和智能指針的使用可以說是各有長短,這里提供劉未鵬的一種解釋,(見參考5RAII部分,文中比較的雖然是JAVAC#,但是實際SEH也是類似JAVA的)大家參考參考。

 

SEH中還提供了一個比較特別的關(guān)鍵字,__leave,MSDN中解釋如下

Allows for immediate termination of the __try block without causing abnormal termination and its performance penalty.

簡而言之就是類似goto語句的拋出異常方式,所謂的沒有性能損失是什么意思呢?看看下面的例子:

#include <iostream>

#include <windows.h>

using namespace std;

 

int main()

{

    int i = 0;

    __try

    {

       __leave;

       i = 1;

    }

    __finally

    {

       cout <<"i: " <<i <<" finally here." <<endl;

    }

 

 

    cout <<"Continue running" <<endl;

    getchar();

}

 

 

輸出:

i: 0 finally here.

Continue running

實際就是類似Goto語句,沒有性能損失指什么?一般的異常拋出也是沒有性能損失的。

MSDN解釋如下:

The __leave keyword

The __leave keyword is valid within a try-finally statement block. The effect of __leave is to jump to the end of the try-finally block. The termination handler is immediately executed. Although a goto statement can be used to accomplish the same result, a goto statement causes stack unwinding. The __leave statement is more efficient because it does not involve stack unwinding.

 

意思就是沒有stack unwinding,問題是。。。。。。如下例,實際會導(dǎo)致編譯錯誤,所以實在不清楚到__leave到底干啥的,我實際中也從來沒有用過此關(guān)鍵字。

 

#include <iostream>

#include <windows.h>

using namespace std;

 

 

void fun()

{

    __leave;

}

 

int main()

{

    __try

    {

       fun();

    }

    __finally

    {

       cout <<" finally here." <<endl;

    }

 

 

    cout <<"Continue running" <<endl;

    getchar();

}

 

三、   提高篇

1.      SEH的優(yōu)點

1)    一個很大的優(yōu)點就是其對異常進程的完全控制,這一點是C++異常所沒有的,因為其遵循的是所謂的終止設(shè)定。

這一點是通過except中的表達式來控制的(在前面的例子中我都是用1表示,實際也就是使用了EXCEPTION_EXECUTE_HANDLER方式。

EXCEPTION_CONTINUE_EXECUTION (–1)   表示在異常發(fā)生的地方繼續(xù)執(zhí)行,表示處理過后,程序可以繼續(xù)執(zhí)行下去。 C++中沒有此語義。

EXCEPTION_CONTINUE_SEARCH (0)   異常沒有處理,繼續(xù)向上拋出。類似C++throw;

EXCEPTION_EXECUTE_HANDLER (1)  異常被處理,從異常處理這一層開始繼續(xù)執(zhí)行。 類似C++處理異常后不再拋出。

 

 

2)    操作系統(tǒng)特性,不僅僅意味著你可以在更多場合使用SEH(甚至在匯編語言中使用),實際對異常處理的功能也更加強大,甚至是程序的嚴重錯誤也能恢復(fù)(不僅僅是一般的異常),比如,除0錯誤,訪問非法地址(包括空指針的使用)等。這里可以用一個例子來說明:

#include <iostream>

#include <windows.h>

using namespace std;

 

 

 

int main()

{

    __try

    {

       int *p = NULL;

       *p = 0;

    }

    __except(1)

    {

       cout <<"catch that" <<endl;

    }

 

 

    cout <<"Continue running" <<endl;

    getchar();

}

 

輸出:

catch that

Continue running

C++中這樣的情況會導(dǎo)致程序直接崩潰的,這一點好好利用,可以使得你的程序穩(wěn)定性大增,以彌補C++中很多的不足。但是,問題又來了,假如異常都被這樣處理了,甚至沒有聲息,非常不符合發(fā)生錯誤時死的壯烈的錯誤處理原則。。。。。。。很可能導(dǎo)致程序一堆錯誤,你甚至不知道為什么,這樣不利于發(fā)現(xiàn)錯誤。

但是,SEHMS提供的另外的特性MiniDump可以完美的配合在一起,使得錯誤得到控制,但是錯誤情況也能捕獲到,稍微的緩解了這種難處(其實也說不上完美解決)。

這一點需要使用者自己權(quán)衡,看看到底開發(fā)進入了哪個階段,哪個更加重要,假如是服務(wù)器程序,那么在正式跑著的時候,每崩潰一次就是實際的損失。。。所以在后期可以考慮用這種方式。

關(guān)于這方面的信息,在下一次在詳細講解。

 

2.      SEH的缺點

其實還是有的,因為是為操作系統(tǒng)設(shè)計的,實際類似為C設(shè)計,那么,根本就不知道C++中類/對象的概念,所以,實際上不能識別并且正確的與C++/對象共存,這一點使用C++的需要特別注意,比如下例的程序根本不能通過編譯。

例一:

int main()

{

    CMyClass o;

    __try

    {

    }

    __except(1)

    {

       cout <<"catch that" <<endl;

    }

 

 

    cout <<"Continue running" <<endl;

    getchar();

}

 

例二:

 

int main()

{

    __try

    {

       CMyClass o;

    }

    __except(1)

    {

       cout <<"catch that" <<endl;

    }

 

 

    cout <<"Continue running" <<endl;

    getchar();

}

 

 

錯誤信息都為:

warning C4509: 使用了非標準擴展:“main”使用SEH,并且“o”有析構(gòu)函數(shù)

error C2712: 無法在要求對象展開的函數(shù)中使用__try

這點比較遺憾,但是我們還是有折衷的辦法的,那就是利用函數(shù)的特性,這樣可以避開SEH的不足。

比如,希望使用類的使用可以這樣:

這個類利用了上節(jié)的CResourceObserver類,

class CMyClass : public CResourceObserver<CMyClass>

{

 

};

 

void fun()

{

    CMyClass o;

}

 

 

#include <iostream>

#include <windows.h>

using namespace std;

 

 

int main()

{

    __try

    {

       fun();

    }

    __except(1)

    {

       cout <<"catch that" <<endl;

    }

 

 

    cout <<"Continue running" <<endl;

    getchar();

}

 

 

輸出:

class CMyClass Construct.

class CMyClass Deconstruct.

Continue running

可以看到正常的析構(gòu),簡而言之就是將實際類/對象的使用全部放進函數(shù)中,利用函數(shù)對對象生命周期的控制,來避開SEH的不足。

 

 

四、   參考資料

1.     Windows核心編程(Programming Applications for Microsoft Windows,4版,Jeffrey Richter著,黃隴,李虎譯,機械工業(yè)出版社

2.     MSDN—Visual Studio 2005 附帶版,Microsoft

3.     加密與解密,段鋼編著,電子工業(yè)出版社

4.     Windows用戶態(tài)程序高效排錯,熊力著,電子工業(yè)出版社

5. 錯誤處理(Error-Handling):為何、何時、如何(rev#2),劉未鵬(pongba)

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国内精品| 亚洲永久精品大片| 亚洲欧美中文另类| 亚洲精品一区二区三区四区高清| 亚洲男人第一网站| 亚洲视频欧美在线| 亚洲一二三区精品| 亚洲欧美乱综合| 久久精品国产综合| 亚洲国产成人久久综合| 欧美国产日本高清在线| 亚洲国产欧美一区| 亚洲午夜在线| 久久精品视频免费| 欧美国产精品一区| 国产精品欧美风情| 好吊日精品视频| 亚洲精品中文字幕有码专区| 亚洲永久精品大片| 久久综合久久久久88| 最新国产精品拍自在线播放| 亚洲视频一区二区在线观看 | 久久久国产一区二区三区| 久久综合一区二区| 欧美人与禽性xxxxx杂性| 国产日韩欧美一区在线| 亚洲日韩欧美视频一区| 久久精品国产亚洲a| 亚洲国产成人久久综合| 欧美亚洲在线| 欧美午夜视频在线观看| 亚洲国产精品一区二区www在线| 亚洲视频精品在线| 亚洲电影中文字幕| 久久久久久久久蜜桃| 国产精品久久久久久一区二区三区| 亚洲第一福利视频| 久久精品欧美日韩精品| 99一区二区| 免费亚洲网站| 国产视频一区欧美| 亚洲一区二区三区四区中文 | 久久精品99国产精品日本| 亚洲精选视频免费看| 另类亚洲自拍| 国产日韩一区二区| 午夜亚洲性色视频| 亚洲美女在线观看| 欧美国产综合视频| 亚洲欧洲日产国产网站| 久久一区二区三区av| 午夜视频精品| 国产欧美日韩高清| 欧美一区二区国产| 亚洲综合三区| 国产欧美日韩中文字幕在线| 香蕉久久国产| 国产精品久久久久久一区二区三区 | 这里只有精品电影| 欧美国产精品一区| 日韩亚洲在线观看| 亚洲黄页一区| 欧美精品免费看| 99精品欧美一区| 亚洲精品孕妇| 国产精品99一区| 亚洲男人的天堂在线aⅴ视频| 亚洲午夜视频| 国产一区二区三区四区老人| 久久米奇亚洲| 麻豆freexxxx性91精品| 亚洲精品永久免费精品| 91久久中文字幕| 欧美精品一区二区三区很污很色的| 亚洲精品视频免费在线观看| 91久久国产综合久久| 国产精品a级| 久久精品三级| 老巨人导航500精品| 99国产精品久久久久老师| 一区二区三区四区五区精品视频| 国产精品乱码久久久久久| 久久久夜精品| 欧美日韩国产限制| 久久久久久久久岛国免费| 男女激情久久| 亚洲影院免费| 久久午夜视频| 亚洲一区制服诱惑| 久久久久久999| 亚洲图片欧美一区| 欧美有码在线观看视频| 91久久在线观看| 亚洲一级在线观看| 狠狠色噜噜狠狠色综合久| 亚洲黄色成人久久久| 国产精品美女久久久| 欧美成人自拍视频| 欧美四级剧情无删版影片| 久久在线免费视频| 欧美午夜视频网站| 欧美高清影院| 国产精品外国| 亚洲人成亚洲人成在线观看图片| 国产情侣久久| 亚洲免费观看高清完整版在线观看熊 | 欧美大片一区| 国产欧美va欧美不卡在线| 亚洲福利视频一区二区| 国产精品爽爽ⅴa在线观看| 欧美黄色影院| 国产字幕视频一区二区| 日韩视频一区| 亚洲国产欧美一区二区三区丁香婷| 亚洲午夜久久久久久久久电影院| 亚洲日本理论电影| 久久久91精品国产一区二区三区 | 亚洲天堂免费观看| 亚洲日本免费电影| 久久久久久久高潮| 欧美在线视频一区| 国产精品激情偷乱一区二区∴| 亚洲国内高清视频| 亚洲国产欧美一区二区三区同亚洲 | 亚洲人成7777| 亚洲国产精品成人精品| 久久本道综合色狠狠五月| 亚洲欧美在线播放| 国产精品v片在线观看不卡 | 亚洲在线免费观看| 欧美激情亚洲视频| 亚洲国产精品精华液2区45| 亚洲国产欧美一区| 美女诱惑黄网站一区| 亚洲成人中文| 最新国产乱人伦偷精品免费网站| 久久久无码精品亚洲日韩按摩| 欧美一区综合| 激情综合在线| 久久天堂国产精品| 亚洲第一级黄色片| 日韩亚洲精品视频| 欧美日韩在线播放一区二区| 一区二区三区四区国产精品| 欧美一区二区精美| 国产视频精品va久久久久久| 欧美亚洲视频| 欧美成人精品不卡视频在线观看 | 亚洲激情第一页| 一区二区福利| 国产精品户外野外| 欧美有码视频| 亚洲国内在线| 西西裸体人体做爰大胆久久久| 国产午夜久久久久| 欧美日韩国产在线播放| 老鸭窝亚洲一区二区三区| 亚洲成色最大综合在线| 99在线观看免费视频精品观看| 欧美性开放视频| 久久精品日产第一区二区三区 | 亚洲一区二区免费视频| 久久精品国产2020观看福利| 亚洲福利视频网| 欧美日韩综合视频| 久久久久久噜噜噜久久久精品| 亚洲电影在线| 午夜伦欧美伦电影理论片| 136国产福利精品导航网址应用| 欧美激情免费在线| 亚洲——在线| 亚洲激情不卡| 另类成人小视频在线| 亚洲午夜成aⅴ人片| 狠狠色狠狠色综合| 欧美无砖砖区免费| 久久午夜电影| 欧美一区二区视频在线| 亚洲国产日韩欧美在线图片| 午夜久久久久久久久久一区二区| 亚洲黄色av| 国产亚洲一本大道中文在线| 欧美日韩成人综合在线一区二区| 午夜精品福利在线观看| 亚洲精品国产品国语在线app| 午夜精品福利一区二区蜜股av| 亚洲国产视频一区| 国产模特精品视频久久久久| 欧美精品日日鲁夜夜添| 久久久青草青青国产亚洲免观| 亚洲永久免费av| 亚洲精品一区二区网址| 欧美不卡一卡二卡免费版| 久久久久国色av免费看影院 | 亚洲片区在线| 欧美黄色片免费观看| 嫩草成人www欧美| 久久爱www久久做| 亚洲欧美精品在线| 亚洲一区二区三区三|