異常和中斷是程序運行時比較重要的2個概念, 異常通常是由程序內部引起的(比較常見的如堆棧溢出, 空指針訪問等),中斷通常是由外部系統引起的, 外部產生的中斷在應用程序中很多時候會以事件或回調的方式通知出來(比如常見的IO事件)。
Windows上應用程序的異常處理是以SEH(structure exception handler)的方式提供的, 關于SEH的實現原理,這里有篇不錯的文章可以參考《棧溢出中利用SEH》。
關于SEH的使用,主要包括終止處理(finally)和異常處理(exception).
(1)終止處理主要是由編譯器實現的,比如下面代碼
__try
{
...
__leave
...
}
__finally
{
...
}
無論是你在try塊中過早的return還是在try中發生了異常, 編譯器都會確保在任何情況下你的終止處理(finally)代碼都能得到執行。
(2)異常處理主要是由操作系統來實現的, 比如下面代碼
__try
{
...
}
__except(filter function)
{
...
}
其中filter function可返回以下類型:
EXCEPTION_EXECUTE_HANDLER: 這是告訴系統, 我認識這個異常,請執行我的異常處理代碼,然后從接下來的第一行代碼開始繼續執行
EXCEPTION_CONTINUE_SEARCH: 這個是告訴系統, 我不認識這個異常, 請繼續往外拋異常
EXCEPTION_CONTINUE_EXECUTE: 這個是告訴系統, 我已經在調用filter時修正了這個異常, 請從發生異常的地方繼續執行
比如我們常見的exception code包括:EXCEPTION_ACCESS_VIOLATION, EXCEPTION_STACK_OVERFLOW,EXCEPTION_INT_DIVIDE_BY_ZERO
上面的幾種異常都是硬件異常,是由CPU在運行過程中引發的, 還有一些異常是軟件異常,是我們通過調用系統API RaiseException引發的。
我們知道C++的異常處理大概是這樣的:
try
{
...
}
catch(int a)
{
...
}
catch(...)
{
...
}
思考C++異常和結構化異常(SEH)是 什么關系?
實際C++異常是通過結構化異常中的軟件異常實現的, 也就是通過調用RaiseException實現的, 通過測試我們可以發現VC編譯器C++異常的異常號永遠是0xE06D7363,對應ASCII碼“.msc".
posted on 2014-09-19 21:00
Richard Wei 閱讀(4136)
評論(3) 編輯 收藏 引用