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