C++編譯器怎麼實現異常處理1 (轉)
C++怎麼實現異常處理
:namespace prefix = o ns = "urn:schemas--com::office" />
對於VC++實現異常處理的深入探討
導論
相比較其他傳統的語言,C++的一個變革的特徵是支援異常處理。相對於傳統語言的不清楚容易錯誤的錯誤處理機制,C++的異常處理是一個非常好的替代。在正常的程式碼和錯誤處理程式碼之間清楚的分割使得非常整潔和宜於維護。本文討論編譯器怎麼實現異常處理。假設讀者熟悉異常處理的語法。 本文包含一個異常處理的VC++的庫來替代VC++的異常處理,使用這個:
install_my_handler();
在這以後,程式中發生的任何異常(包含丟擲異常到 stack unwinding,catch塊和繼續)都使用我自己的異常處理庫。
譯者注:當異常出現時,正常的執行流被中斷,異常處理機制開始在當前範圍尋找匹配的處理函式。如果找不到,把當前函式從棧中彈出,在呼叫者中繼續尋找。這個過程稱為tips/tipview.?content_id=1614" target=_blank>stack unwinding
像其他C++特徵一樣,C++的標準並沒有指定異常處理的實現機制。這使得C++實現者可以使用任何實現機制。我將講述VC++怎麼實現的。VC++把異常處理置於SHE(Structured exception hangling)的上面。SHE是操作提供的結構化的異常處理。
SHE導論
在本討論中,我將考慮那些顯式的異常。例如被0除,空指標訪問等。當異常出現,中斷會產生,控制被轉到OS。 OS呼叫異常處理,檢查從異常發出的函式開始的函式呼叫順序,執行stack unwinding和控制轉移。我們可以開發自己的異常處理函式,在OS中註冊。OS就會在異常事件時呼叫它們。
Windows定義了一個特別的結構用來註冊:
EXCEPTION_REGISTRATION:
struct EXCEPTION_REGISTRATION
{
EXCEPTION_REGISTRATION *prev;
D handler;
};
要註冊自己的異常處理函式,建立這個結構並將它的地址儲存在段(由FS暫存器指向)的0偏移處。如下面的偽指令:
mov FS:[0], exc_regp
結構中的prev欄位表示EXCEPTION_REGISTRATION連結串列。當我們註冊了這個EXCEPTION_REGISTRATION結構,我們使用這個prev欄位儲存以前註冊的結構的地址。
關於異常回撥函式,windows要求異常處理的訊號,定義在excp.h中:
EXCEPTION_DISPOSITION (*handler)(
_EXCEPTION_RECORD *ExcRecord,
void * EstablisherFrame,
_CONTEXT *ContextRecord,
void * DispatcherContext);
現在你可以忽略所有的引數和返回型別。下面的程式在OS中註冊了一個異常處理控制程式碼並將產生一個被0除的異常。這個異常被抓到並將列印一個訊息:
#include
#include
using std::cout;
using std::endl;
struct EXCEPTION_REGISTRATION
{
EXCEPTION_REGISTRATION *prev;
DWORD handler;
};
EXCEPTION_DISPOSITION myHandler(
_EXCEPTION_RECORD *ExcRecord,
void * EstablisherFrame,
_CONTEXT *ContextRecord,
void * DispatcherContext)
{
cout << "In the exception handler" << endl;
cout << "Just a demo. exiting..." << endl;
exit(0);
return ExceptionContinueExecution; //will not reach here
}
int g_div = 0;
void bar()
{
//initialize EXCEPTION_REGISTRATION structure
EXCEPTION_REGISTRATION reg, *preg = ®
reg.handler = (DWORD)myHandler;
//get the current head of the exception handling chain
DWORD prev;
_asm
{
mov EAX, FS:[0]
mov prev, EAX
}
reg.prev = (EXCEPTION_REGISTRATION*) prev;
//register it!
_asm
{
mov EAX, preg
mov FS:[0], EAX
}
//generate the exception
int j = 10 / g_div; //Exception. Div by 0.
}
int main()
{
bar();
return 0;
}
/*-------output-------------------
In the exception handler
Just a demo. exiting...
---------------------------------*/
注意:windows嚴格地定義了一個規則:EXCEPTION_REGISTRATION結構應該在棧內,並且要在以前的程式碼的低的地址。規則不滿足,windows將中止程式。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991773/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C++編譯器怎麼實現異常處理3 (轉)C++編譯
- C++編譯器怎麼實現異常處理2 (轉)C++編譯
- c++ 異常處理(1)C++
- c++異常處理 (轉)C++
- C++ 異常處理機制的實現C++
- C++ 異常處理C++
- C++異常處理C++
- dns異常怎麼修復 dns配置異常怎麼處理DNS
- 異常處理1
- [翻譯]-異常處理最佳實踐
- c++異常處理格式C++
- c++ 異常處理(2)C++
- 異常處理 (轉)
- C與C++中的異常處理2(part1) (轉)C++
- C與C++中的異常處理 (轉)C++
- dns異常是什麼意思 dns異常怎麼處理DNS
- dns解析狀態異常怎麼處理 dns解析異常怎麼修復DNS
- C++異常處理機制C++
- windows核心程式設計---未處理異常,向量化異常處理與C++異常Windows程式設計C++
- 【C++】 C++異常捕捉和處理C++
- 異常處理方法 (轉)
- 【轉】Oracle 異常處理Oracle
- C與C++中的異常處理11 (轉)C++
- C與C++中的異常處理13 (轉)C++
- C與C++中的異常處理12 (轉)C++
- C與C++中的異常處理14 (轉)C++
- C與C++中的異常處理15 (轉)C++
- C與C++中的異常處理16 (轉)C++
- C與C++中的異常處理17 (轉)C++
- C與C++中的異常處理3 (轉)C++
- C與C++中的異常處理4 (轉)C++
- C與C++中的異常處理5 (轉)C++
- C與C++中的異常處理7 (轉)C++
- C與C++中的異常處理6 (轉)C++
- C與C++中的異常處理9 (轉)C++
- C與C++中的異常處理8 (轉)C++
- C與C++中的異常處理10 (轉)C++
- .NET中異常處理的最佳實踐(譯)