日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

结束处理程序——Windows核心编程学习手札之二十三

發(fā)布時(shí)間:2025/4/16 windows 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 结束处理程序——Windows核心编程学习手札之二十三 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

結(jié)束處理程序

——Windows核心編程學(xué)習(xí)手札之二十三

使用SEH可以只關(guān)注程序要完成任務(wù),而運(yùn)行中發(fā)生的錯(cuò)誤,系統(tǒng)將會(huì)發(fā)現(xiàn)并通知。Windows引入SHE是為了便于操作系統(tǒng)的開發(fā),使用SHE所造成的負(fù)擔(dān)主要由編譯程序來(lái)承擔(dān),而不是由操作系統(tǒng)承擔(dān)。當(dāng)異常塊(exception block)出現(xiàn)時(shí),編譯程序要生成特殊的代碼,產(chǎn)生一些表(table)來(lái)支持處理SHE的數(shù)據(jù)結(jié)構(gòu),提供回調(diào)(callback)函數(shù),操作系統(tǒng)可以調(diào)用這些函數(shù),保證異常塊被處理。編譯程序還負(fù)責(zé)準(zhǔn)備棧結(jié)構(gòu)和其他內(nèi)部信息,供操作系統(tǒng)使用和參考。在編譯程序中增加SHE支持,不同的編譯商會(huì)以不同的方式實(shí)現(xiàn)SEHSHE實(shí)際包含兩個(gè)主要功能:結(jié)束處理(termination handling)和異常處理(exception handling)。

一個(gè)結(jié)束處理程序能夠確保去調(diào)用和執(zhí)行一個(gè)代碼塊(結(jié)束處理程序,termination handling),而不管另外一段代碼(保護(hù)體,guarded body)是如何退出,結(jié)束處理程序的文法結(jié)構(gòu)如下:

?????? __try{

???????????????????? //guarded body

??????????? 。。。

???????? }

?????? __finally{

????????????? ?? //termination handler

?????????? 。。。

?????? }

__try__finally關(guān)鍵字用來(lái)標(biāo)出處理程序兩段代碼的輪廓,操作系統(tǒng)和編譯程序共同確保結(jié)束處理程序中的__finally代碼塊能夠被執(zhí)行,不管保護(hù)體(try塊)是如何退出的,不論保護(hù)體中使用return,還是goto,或者是longjump,結(jié)束處理程序(finally塊)都將被調(diào)用。

盡管結(jié)束處理程序可以捕捉try塊過(guò)早退出的大多數(shù)情況,但當(dāng)線程或進(jìn)程被結(jié)束時(shí),卻不能引起finally塊中的代碼執(zhí)行。當(dāng)調(diào)用ExitThreadExitProcess時(shí),將立即結(jié)束線程或進(jìn)程,而不會(huì)執(zhí)行finally塊中的任何代碼,另外,由于某個(gè)程序調(diào)用terminateThreadterminateProcess,線程或進(jìn)程將死掉,finally塊中的代碼也不執(zhí)行。某些C運(yùn)行期函數(shù)(如abort)要調(diào)用ExitProcess,也使finally塊中的代碼不能執(zhí)行,雖然沒(méi)有辦法阻止其他程序結(jié)束線程或進(jìn)程,但可以避免過(guò)早調(diào)用ExitThreadExitProcess,以執(zhí)行finally塊中代碼。最好將returncontinuebreakgoto等語(yǔ)句從結(jié)束處理程序的try塊和finally塊中移出去,放在結(jié)束處理程序的外面,這樣使編譯程序產(chǎn)生較小的代碼,因?yàn)椴恍枰俨蹲?/span>try塊中的過(guò)早退出,也使編譯程序產(chǎn)生更快的代碼(因?yàn)閳?zhí)行局部展開的指令也不少),另外代碼更容易閱讀和維護(hù)。

為避免在try塊中使用return語(yǔ)句,microsoftC/C++編譯程序中增加了__leave關(guān)鍵字。在try塊中使用__leave關(guān)鍵字會(huì)引起跳轉(zhuǎn)到try塊的結(jié)尾,即跳轉(zhuǎn)到try塊的右大括號(hào),由于控制流自然地從try塊中退出并進(jìn)入finally塊,不產(chǎn)生系統(tǒng)開銷,不過(guò)需要增加BOOL型變量來(lái)指示函數(shù)的成功或失敗,當(dāng)然這個(gè)代價(jià)是很小的。按照這個(gè)方式利用結(jié)束處理程序來(lái)設(shè)計(jì)函數(shù)時(shí),需要在進(jìn)入try塊之前,將所有資源句柄初始化為無(wú)效的值,然后在finally塊中查看那些資源被成功的分配,就可以知道那些要釋放。另外一種確定需要釋放資源的辦法是對(duì)成功分配的資源設(shè)置一個(gè)標(biāo)志,然后在finally塊中的代碼檢查標(biāo)志的狀態(tài),來(lái)確定資源是否被釋放。

區(qū)分強(qiáng)制執(zhí)行finally塊的情況:

1)從try塊中進(jìn)入finally塊的正常控制流;

2)局部展開:從try塊中過(guò)早退出(gotolongjumpcontiunebreakreturn等)強(qiáng)制控制轉(zhuǎn)移到finally塊,由于系統(tǒng)開銷比較大,盡量避免在try塊中過(guò)早退出,可使用__leave代替return

3)全局展開(global unwind),發(fā)生時(shí)沒(méi)有明顯標(biāo)識(shí),如引起一個(gè)內(nèi)存訪問(wèn)違規(guī)(memory access violation),一個(gè)全局展就會(huì)在finally塊執(zhí)行。

為了確定是那種情況引起finally塊執(zhí)行,可調(diào)用內(nèi)部函數(shù)(或內(nèi)蘊(yùn)函數(shù),intrinsic functionAbnormal Termination

?????? BOOL AbnormalTermination();

這個(gè)內(nèi)部函數(shù)只在finally塊中調(diào)用,返回一個(gè)Boolean值,指出與finally塊相結(jié)合的try塊是否過(guò)早退出,如果控制流離開try塊并自然進(jìn)入finally塊,則返回FALSE;如果控制流非正常退出try塊(由于goto/return/break/contiune語(yǔ)句引起的局部展開),或由于內(nèi)部訪問(wèn)違規(guī)或其他異常引起的全局展開,將返回TRUE,這里沒(méi)發(fā)區(qū)別finally塊的執(zhí)行是由于局部展開還是全局展開。

內(nèi)部函數(shù)是編譯程序識(shí)別的一種特殊函數(shù),編譯程序?yàn)閮?nèi)部函數(shù)產(chǎn)生內(nèi)聯(lián)(inline)代碼而不是生成調(diào)用函數(shù)的代碼,例如,memcpy是一個(gè)內(nèi)部函數(shù)(如果指定/Oi編譯程序開關(guān))當(dāng)編譯程序看到一個(gè)對(duì)memcpy的調(diào)用,直接將memcpy的代碼插入調(diào)用memcpy 函數(shù)中,而不是生成一個(gè)對(duì)memcpy函數(shù)的調(diào)用,其作用是代碼的長(zhǎng)度增加了,但執(zhí)行速度加快了。

利用結(jié)束處理程序的理由:

1)簡(jiǎn)單錯(cuò)誤處理,所有清理工作在一個(gè)位置并且保證被執(zhí)行;

2)提高程序的可讀性;

3)使代碼更加容易維護(hù);

4)如果使用得當(dāng),具有最小的系統(tǒng)開銷。

?

總結(jié)

以上是生活随笔為你收集整理的结束处理程序——Windows核心编程学习手札之二十三的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。