專(zhuān)利名稱:對(duì)所引起的異常的通知的制作方法
對(duì)所引起的異常的通知背景計(jì)算機(jī)程序通常包含兩種類(lèi)型的代碼實(shí)現(xiàn)程序的目標(biāo)的指令,和包含用于從發(fā)生的不期望的條件或不尋常的條件恢復(fù)或響應(yīng)于發(fā)生的不期望的條件或不尋常的條件的指令的出錯(cuò)處理代碼。出錯(cuò)處理可以包括解決從因?yàn)槲募辉谒?qǐng)求的位置而引起的文件打開(kāi)失敗到訪問(wèn)不屬于該程序的存儲(chǔ)器(例如,程序未分配的存儲(chǔ)器或已經(jīng)釋放的存儲(chǔ)器)的任何問(wèn)題。軟件異常是一種類(lèi)型的出錯(cuò)通知范例。異常是在檢測(cè)到在程序線程的正常執(zhí)行中不期望的條件時(shí)引起的信號(hào)。許多代理可以檢測(cè)不正確的條件并引起異常。對(duì)于在托管環(huán)境中運(yùn)行的應(yīng)用,可以由程序代碼(或程序使用的庫(kù)代碼)、運(yùn)行時(shí)引擎和應(yīng)用調(diào)用的非托管代碼引起異常。異常允許開(kāi)發(fā)者快速且直接地寫(xiě)出用于正常情況的軟件代碼,且在預(yù)定義的區(qū)域中包含用于處理出錯(cuò)(例如,異常)的代碼。使用異常,程序通常用 “try”塊包圍一個(gè)指令塊,且在異常條件發(fā)生時(shí),程序離開(kāi)try塊并執(zhí)行一個(gè)或多個(gè)有條件地執(zhí)行的塊。在執(zhí)行的線程上引起的異常跟隨該線程通過(guò)本機(jī)代碼和托管代碼且跨越各應(yīng)用域(例如,微軟.NET AppDomain) 0如果程序不處理異常,則異常通常被呈現(xiàn)給操作系統(tǒng)并被看作是未經(jīng)處理的異常。如果程序理解導(dǎo)致異常發(fā)生的條件,則程序可以處理異常。異常表示在程序的執(zhí)行期間廣泛的不期望的條件。在程序被看作是邏輯堆棧層時(shí),異??梢栽诟鞣N級(jí)別發(fā)生。例如,操作系統(tǒng)可以提供異常(例如,結(jié)構(gòu)化異常處理(SEH)),底層運(yùn)行時(shí)可以提供異常(例如,C語(yǔ)言運(yùn)行時(shí)或微軟.NET公共語(yǔ)言運(yùn)行時(shí)(CLR)),且程序本身可以提供由用來(lái)創(chuàng)建該程序的語(yǔ)言定義的異常(例如,C語(yǔ)言異常、微軟.NET異常等等)。對(duì)于高級(jí)語(yǔ)言,環(huán)境可以將這些異常中的每一種包裝成程序的語(yǔ)言所識(shí)別的一種或多種類(lèi)型。 例如,微軟.NET將任何本機(jī)異常表示為從微軟.NET異常類(lèi)繼承的特定托管異常。軟件已經(jīng)變得如此復(fù)雜,以至于組件重用是常見(jiàn)的,且許多軟件程序調(diào)用外部組件或在內(nèi)部包括不是由程序作者寫(xiě)成或驗(yàn)證的組件(例如,通過(guò)靜態(tài)鏈接)。例如,數(shù)據(jù)挖掘應(yīng)用可以調(diào)用數(shù)據(jù)庫(kù)用于建立到數(shù)據(jù)庫(kù)的連接并響應(yīng)于查詢接收來(lái)自該數(shù)據(jù)庫(kù)的數(shù)據(jù)。 另外,程序可以包括與程序的主范例不同的全平臺(tái)范例。例如,本機(jī)C++應(yīng)用程序可以調(diào)用托管微軟.NET軟件類(lèi)以執(zhí)行某些動(dòng)作。這樣的復(fù)雜系統(tǒng)的任何部分可以包括系統(tǒng)的其他部分不預(yù)期或不處理的出錯(cuò)和異常。例如,如果本機(jī)應(yīng)用調(diào)用托管代碼,且托管代碼碰到異?;蚱渌收?,則可能損壞本機(jī)應(yīng)用狀態(tài),或者本機(jī)應(yīng)用可以終止,這是因?yàn)楸緳C(jī)應(yīng)用程序不知道或不被設(shè)計(jì)為處理該故障。相反,托管應(yīng)用可以調(diào)用損壞該應(yīng)用狀態(tài)或經(jīng)歷某種其他故障的本機(jī)代碼。用于離線分析的關(guān)于異常的最相關(guān)的信息往往知道發(fā)生過(guò)異常。不幸的是,對(duì)于應(yīng)用尤其是包括一個(gè)或多個(gè)第三方組件或插件的應(yīng)用,難以檢測(cè)每一異常并將關(guān)于異常的信息記入日志。例如,軟件代碼可以捕捉異常并(正確地或錯(cuò)誤地)處理該異常,使得其他應(yīng)用代碼不可能檢測(cè)到發(fā)生過(guò)異常。如果應(yīng)用是在調(diào)試器中運(yùn)行,則調(diào)試器通常在程序被允許處理異常之前給開(kāi)發(fā)者提供所引起的異常的通知。然而,在正規(guī)消費(fèi)者場(chǎng)景中,在調(diào)試器中運(yùn)行應(yīng)用是不實(shí)用的。
現(xiàn)今存在用于在正常的應(yīng)用流之外處理異常的各種機(jī)制。作為一個(gè)示例,應(yīng)用可以提供未經(jīng)處理的異常過(guò)濾器,該未經(jīng)處理的異常過(guò)濾器接收不另外被應(yīng)用捕捉的任何異常。作為另一示例,微軟Windows提供被稱為Vectored Exception Handling(矢量化異常處理)的機(jī)制,在引起本機(jī)異常時(shí),該機(jī)制允許程序員將過(guò)濾器添加到由OS執(zhí)行的一系列過(guò)濾器。從托管代碼勾取過(guò)濾器可以允許相似的功能。然而,這并不被推薦,且應(yīng)用異常處理可以導(dǎo)致程序狀態(tài)中的改變,這使得未經(jīng)處理的異常過(guò)濾器難以記錄關(guān)于異常的原因的足夠的相關(guān)細(xì)節(jié)。將異常傳遞給程序的異常處理區(qū)域(通常是catch(捕捉)塊或 filter(過(guò)濾器)塊)涉及執(zhí)行大量工作的異常系統(tǒng)。程序代碼不能在不接受異常供處理的情況下就檢查該異常,這是在處理程序接收異常之前可以修改異常狀態(tài)和程序狀態(tài)的動(dòng)作。概述在此描述在應(yīng)用異常處理代碼已經(jīng)運(yùn)行之前提供軟件異常已經(jīng)發(fā)生的提前通知的異常通知系統(tǒng)。該系統(tǒng)允許開(kāi)發(fā)者有機(jī)會(huì)在運(yùn)行時(shí)的異常系統(tǒng)開(kāi)始對(duì)處理程序的搜索之前檢查導(dǎo)致異常的程序狀態(tài)。異常通知系統(tǒng)從程序代碼接收到注冊(cè)處理程序以便在異常發(fā)生時(shí)接收提前通知的注冊(cè)請(qǐng)求。在異常發(fā)生時(shí),系統(tǒng)引起調(diào)用每一已注冊(cè)的處理程序的事件。在處理程序返回之后,系統(tǒng)執(zhí)行正常的異常處理,以使得提前通知不改變現(xiàn)有的異常處理行為。異常通知系統(tǒng)允許程序檢查和記錄異常,如同在程序正在調(diào)試器下運(yùn)行時(shí)發(fā)生異常的情況下開(kāi)發(fā)者可以進(jìn)行的那樣。通過(guò)允許開(kāi)發(fā)者以編程方式檢查異常和程序狀態(tài),程序代碼可以捕捉關(guān)于異常的原因的詳盡信息以便允許進(jìn)一步的離線分析。另外,可以接收用于與程序相關(guān)聯(lián)的所有線程的通知,以使得程序可以檢測(cè)和存儲(chǔ)與在開(kāi)發(fā)者自己的代碼之外引起的異常有關(guān)的信息。因而,異常通知系統(tǒng)允許開(kāi)發(fā)者通過(guò)接收關(guān)于程序代碼中的不期望的條件的更多信息來(lái)改善他們的程序。提供本概述以便以簡(jiǎn)化形式介紹下面在詳細(xì)描述中進(jìn)一步描述的概念的選集。本概述不旨在標(biāo)識(shí)所要求保護(hù)的本主題的關(guān)鍵特征或必要特征,也不預(yù)期被用來(lái)限制所要求保護(hù)的本主題的范圍。附圖簡(jiǎn)述
圖1是示出在一種實(shí)施方式中異常通知系統(tǒng)的各組件的框圖。圖2是示出在一種實(shí)施方式中系統(tǒng)接收向其提供異常的提前通知的處理程序的處理的流程圖。圖3是示出在一種實(shí)施方式中在異常被引起時(shí)系統(tǒng)的處理的流程圖。詳細(xì)描述在此描述在異常處理代碼已經(jīng)運(yùn)行之前提供異常已經(jīng)發(fā)生的提前通知的異常通知系統(tǒng)。該系統(tǒng)允許開(kāi)發(fā)者有機(jī)會(huì)在運(yùn)行時(shí)的異常系統(tǒng)開(kāi)始對(duì)處理程序的搜索之前檢查導(dǎo)致異常的程序狀態(tài)。異常通知系統(tǒng)從程序代碼接收注冊(cè)處理程序以便在異常發(fā)生時(shí)接收提前通知的注冊(cè)請(qǐng)求。例如,程序代碼可以提供在不影響正常的異常處理代碼的情況下記錄狀態(tài)以供離線診斷的處理程序。在程序終止時(shí),程序正常地執(zhí)行定制記錄。然而,異常通知系統(tǒng)允許在程序處于引起異常的狀態(tài)的同時(shí)程序執(zhí)行記錄。在異常發(fā)生時(shí),系統(tǒng)引起調(diào)用每一已注冊(cè)的處理程序的事件。在處理程序返回之后,系統(tǒng)執(zhí)行正常的異常處理,以使得提前通知不改變現(xiàn)有的異常處理行為。先前,開(kāi)發(fā)者需要使用影響程序異常處理語(yǔ)義的catch塊或filter塊。異常通知系統(tǒng)允許程序檢查和記錄異常,如同在程序正在調(diào)試器下運(yùn)行時(shí)發(fā)生異常的情況下開(kāi)發(fā)者可以進(jìn)行的那樣。然而,系統(tǒng)不使用調(diào)試器,也不招致與在調(diào)試器中運(yùn)行進(jìn)程相關(guān)聯(lián)的開(kāi)銷(xiāo)。通過(guò)使得開(kāi)發(fā)者能夠以編程方式檢查異常和程序狀態(tài),程序代碼可以捕捉與異常的原因有關(guān)的詳盡信息以便允許進(jìn)一步的離線分析。另外,可以接收用于與應(yīng)用(例如,在微軟.NET AppDomain內(nèi)的應(yīng)用)相關(guān)聯(lián)的所有線程的通知,以使得應(yīng)用可以檢測(cè)和存儲(chǔ)與在開(kāi)發(fā)者自己的代碼之外引起的異常有關(guān)的信息(例如,對(duì)于OS、運(yùn)行時(shí)或第三方庫(kù)代碼中的異常)。因而,異常通知系統(tǒng)允許開(kāi)發(fā)者通過(guò)接收關(guān)于程序代碼中的不期望的條件的更多信息來(lái)改善他們的程序。圖1是示出在一種實(shí)施方式中異常通知系統(tǒng)的各組件的框圖。系統(tǒng)100包括處理程序注冊(cè)組件110、異常檢測(cè)組件120、對(duì)象發(fā)現(xiàn)組件130、異常通知組件140和異常處理組件150。在此進(jìn)一步詳細(xì)描述這些組件中的每一個(gè)。處理程序注冊(cè)組件110從應(yīng)用接收對(duì)處理程序進(jìn)行注冊(cè)以便得到在異常發(fā)生時(shí)由系統(tǒng)100所提供的提前通知的請(qǐng)求。組件110可以允許應(yīng)用對(duì)在異常發(fā)生時(shí)系統(tǒng)100將調(diào)用的多個(gè)處理程序進(jìn)行注冊(cè)。處理程序通常滿足由處理程序注冊(cè)組件110提供的規(guī)范, 包括接受某些參數(shù)并且作為特定的類(lèi)的一部分。例如,使用微軟.NET,組件110可以期望已注冊(cè)的處理程序是在接受類(lèi)型異常的參數(shù)AppDomain類(lèi)中定義的類(lèi)型的委托。另外,處理程序注冊(cè)組件110可以確定請(qǐng)求者的安全級(jí)別。例如,組件110可以不接受來(lái)自不被標(biāo)記 Security Critical (安全關(guān)鍵)(或等效等級(jí))的請(qǐng)求者的注冊(cè)。在一些實(shí)施方式中, 系統(tǒng)100可以對(duì)處理程序本身施加類(lèi)似的限制,或者可以允許處理程序處于較低的安全級(jí)別(例如,Transparent (透明)或等效等級(jí))。以下是用于在此描述的處理程序的事件處理程序的示例定義。
public sealed class AppDomain {
public event EventHandler<FirstChanceExceptionEventArgs> FirstChanceException;
public class System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs
:EventArgs {
//表示引起的異常
public Exception Exception { get;}
} 在程序正在執(zhí)行的同時(shí),異常檢測(cè)組件120檢測(cè)到異常發(fā)生過(guò)。軟件代碼可以在幀中引起異常或者可以在幀中接收異常。幀是指執(zhí)行的上下文。當(dāng)在線程上執(zhí)行的軟件代碼引起異常時(shí),異常處理邏輯在幀中引起異常。在某些其他情況中,諸如在阻塞的操作系統(tǒng)調(diào)用失敗時(shí)或者在線程跨越組件對(duì)象模型(COM)互操作anterop)邊界調(diào)用軟件代碼時(shí), 異常處理邏輯在幀中接收異常,即使可能最初已經(jīng)在其他地方引起該異常。異??梢砸詫?duì)操作系統(tǒng)異常引起函數(shù)(例如,對(duì)于微軟Windows是RaiseExc印tion)的調(diào)用來(lái)開(kāi)始。操作系統(tǒng)走查線程堆棧以便為異常標(biāo)識(shí)各處理程序并調(diào)用適當(dāng)?shù)奶幚沓绦?。異常通知系統(tǒng)100 具有在操作系統(tǒng)調(diào)用的堆棧上的處理程序,這允許異常檢測(cè)組件120檢測(cè)異常。對(duì)象發(fā)現(xiàn)組件130響應(yīng)于所檢測(cè)的異常來(lái)查找異常狀態(tài),并標(biāo)識(shí)與當(dāng)前線程相關(guān)聯(lián)的應(yīng)用對(duì)象。例如,如果應(yīng)用是微軟.NET應(yīng)用,那么,CLR檢測(cè)異常并標(biāo)識(shí)托管對(duì)象以及與異常狀態(tài)相關(guān)聯(lián)的AppDomain。運(yùn)行時(shí)也在異常類(lèi)的分層結(jié)構(gòu)中確定異常的類(lèi)型。例如,運(yùn)行時(shí)可以將操作系統(tǒng)結(jié)構(gòu)化異常表示為應(yīng)用可以檢測(cè)和處理的托管異常類(lèi)(例如, System. AccessVioIationException 類(lèi))0異常通知組件140調(diào)用已注冊(cè)的應(yīng)用處理程序以便向處理程序通知所檢測(cè)的異常。例如,組件140可以循環(huán)經(jīng)過(guò)每一處理程序并串行地調(diào)用每一個(gè)。異常通知組件140 可以將異常對(duì)象或其他參數(shù)提供給已注冊(cè)的處理程序,處理程序可以通過(guò)異常對(duì)象或其他參數(shù)來(lái)檢索關(guān)于異常的原因的附加信息。例如,在系統(tǒng)100和微軟.NET—起使用時(shí),CLR將托管異常對(duì)象作為異常類(lèi)的正常實(shí)例提供給處理程序,且在應(yīng)用在catch塊中接收異常時(shí)通常可用的所有可用方法和性質(zhì)。如先前所描述,異常處理可以標(biāo)識(shí)與異常狀態(tài)相關(guān)聯(lián)的 AppDomain對(duì)象并將通知提供該AppDomain的委托。在已注冊(cè)的應(yīng)用處理程序已經(jīng)被通知之后,異常處理組件150執(zhí)行傳統(tǒng)的異常處理。本領(lǐng)域中的普通技術(shù)人員將認(rèn)識(shí)到組件150可以執(zhí)行的各種傳統(tǒng)異常處理。例如,組件 150可以執(zhí)行標(biāo)準(zhǔn)的兩遍異常進(jìn)程。在第一遍期間,組件150走查堆棧(例如,使用在即時(shí) (JIT)編譯期間存儲(chǔ)的信息)以便在堆棧上靠近異常發(fā)生的地方的應(yīng)用程序代碼中尋找將接受所引起的類(lèi)型的異常的異常處理塊。在第二遍期間,組件150調(diào)用處理程序以便清除自堆棧的底部(異常在那里發(fā)生)到接受處理程序的幀的應(yīng)用狀態(tài)。這可以例如導(dǎo)致為越界的對(duì)象、最終塊、故障塊等等調(diào)用C++析構(gòu)函數(shù)。第二遍以組件150調(diào)用在第一遍期間所標(biāo)識(shí)的接受處理程序以便允許處理程序處理異常而結(jié)束。然而,在異常通知之后,系統(tǒng)100 不限于任何特定形式的異常處理。例如,系統(tǒng)可以執(zhí)行單遍或其他模型而不是上面作為示例描述的兩遍模型??梢栽谄渖蠈?shí)現(xiàn)該系統(tǒng)的計(jì)算設(shè)備可以包括中央處理單元、存儲(chǔ)器、輸入設(shè)備 (例如,鍵盤(pán)和定點(diǎn)設(shè)備)、輸出設(shè)備(例如,顯示設(shè)備)和存儲(chǔ)設(shè)備(例如,盤(pán)驅(qū)動(dòng)器或其他非易失性存儲(chǔ)介質(zhì))。存儲(chǔ)器和存儲(chǔ)設(shè)備是可以用實(shí)現(xiàn)或啟用該系統(tǒng)的計(jì)算機(jī)可執(zhí)行指令(例如,軟件)編碼的計(jì)算機(jī)可讀存儲(chǔ)介質(zhì)。另外,可以存儲(chǔ)或經(jīng)由諸如通信鏈路上的信號(hào)等的數(shù)據(jù)傳送介質(zhì)傳送數(shù)據(jù)結(jié)構(gòu)和消息結(jié)構(gòu)??梢允褂弥T如因特網(wǎng)、局域網(wǎng)、廣域網(wǎng)、點(diǎn)對(duì)點(diǎn)撥號(hào)連接、蜂窩式電話網(wǎng)絡(luò)等等的各種通信鏈路??梢栽诟鞣N操作環(huán)境中實(shí)現(xiàn)系統(tǒng)的各實(shí)施方式,這些操作環(huán)境包括個(gè)人計(jì)算機(jī)、 服務(wù)器計(jì)算機(jī)、手持式設(shè)備或膝上型設(shè)備、多處理器系統(tǒng)、基于微處理器的系統(tǒng)、可編程消費(fèi)電子設(shè)備、數(shù)碼相機(jī)、網(wǎng)絡(luò)PC、小型計(jì)算機(jī)、大型計(jì)算機(jī)、包括以上系統(tǒng)或設(shè)備中的任一個(gè)在內(nèi)的分布式計(jì)算環(huán)境等等。計(jì)算機(jī)系統(tǒng)可以是蜂窩電話、個(gè)人數(shù)字助理、智能電話、個(gè)人計(jì)算機(jī)、可編程消費(fèi)電子設(shè)備、數(shù)碼相機(jī)等等??梢栽谟梢粋€(gè)或多個(gè)計(jì)算機(jī)或其他設(shè)備執(zhí)行的諸如程序模塊等的計(jì)算機(jī)執(zhí)行指令的一般上下文中描述該系統(tǒng)。一般地,程序模塊包括執(zhí)行特定的任務(wù)或?qū)崿F(xiàn)特定抽象數(shù)據(jù)類(lèi)型的例程、程序、對(duì)象、組件、數(shù)據(jù)結(jié)構(gòu)等等。通常,在各種實(shí)施方式中,程序模塊的功能可以按需組合或分布。圖2是示出在一種實(shí)施方式中異常通知系統(tǒng)接收向其提供提前異常通知的通知處理程序的處理的流程圖。在框210開(kāi)始,系統(tǒng)接收通知處理程序?qū)ο?。?yīng)用模塊可以提供一類(lèi),該類(lèi)的通知處理程序是特定類(lèi)中的類(lèi)型的委托。例如,使用微軟.NET,通知處理程序可以是與應(yīng)用相關(guān)聯(lián)的AppDomain類(lèi)中的類(lèi)型的委托。在框220繼續(xù),系統(tǒng)接收一個(gè)或多個(gè)通知屬性。例如,通知處理程序可以具有該通知處理程序可以處理的一種或多種類(lèi)型或類(lèi)別的異常(例如,損壞狀態(tài)異常)的屬性。類(lèi)型可以是指異常的類(lèi)分層結(jié)構(gòu)中的類(lèi),而類(lèi)別可以是指系統(tǒng)不考慮類(lèi)型而區(qū)分的異常。例如,不考慮類(lèi)型,損壞狀態(tài)異常可以是異常的一個(gè)類(lèi)別。在框230繼續(xù),系統(tǒng)調(diào)用處理程序注冊(cè)函數(shù),處理程序注冊(cè)函數(shù)將所接收的處理程序?qū)ο筇砑拥揭炎?cè)的處理程序的列表以便響應(yīng)于異常發(fā)生而調(diào)用。在一些實(shí)施方式中,系統(tǒng)可以借助處理程序在特定類(lèi)型的類(lèi)上的存在而自動(dòng)地注冊(cè)處理程序(例如,通過(guò)在系統(tǒng)提供默認(rèn)的空方法且如果存在則調(diào)用應(yīng)用的覆蓋那里的繼承)。在這些步驟之后,設(shè)置處理程序?qū)ο笠员阍诋惓0l(fā)生時(shí)調(diào)用。下列步驟示出附加處理,應(yīng)用可以執(zhí)行這些附加處理以便避免例如在應(yīng)用啟動(dòng)期間接收到異常通知,在應(yīng)用啟動(dòng)期間接收異常通知可以產(chǎn)生許多不感興趣的異常。在判定框MO中繼續(xù),如果系統(tǒng)檢測(cè)到包含處理程序?qū)ο蟮膽?yīng)用的啟動(dòng)完成,那么,系統(tǒng)在框250繼續(xù),否則系統(tǒng)循環(huán)到框MO以便等待啟動(dòng)完成。系統(tǒng)可以通過(guò)由操作系統(tǒng)或運(yùn)行時(shí)提供的另一通知來(lái)檢測(cè)到啟動(dòng)完成。在框250中繼續(xù),系統(tǒng)激活已注冊(cè)的處理程序?qū)ο蟮恼{(diào)用。系統(tǒng)可以提供一個(gè)方法,在應(yīng)用的執(zhí)行期間,應(yīng)用可以調(diào)用該方法來(lái)將提前異常通知切換為開(kāi)或關(guān)。例如,在執(zhí)行某些類(lèi)型的操作之前,或者(正如在這里所示出的)在應(yīng)用啟動(dòng)完成之后,應(yīng)用可以開(kāi)啟提前異常通知。在框250之后,這些步驟結(jié)束。圖3是示出在一種實(shí)施方式中在異常被引起時(shí)異常通知系統(tǒng)的處理的流程圖。在框310開(kāi)始,異常通知系統(tǒng)接收異常已經(jīng)被引起的通知。例如,在應(yīng)用或運(yùn)行時(shí)已經(jīng)接收異常以供處理之前,在操作系統(tǒng)內(nèi)可發(fā)生對(duì)所引起的異常的通知。例如,軟件代碼可以調(diào)用諸如由微軟Windows提供的RaiseException等的操作系統(tǒng)函數(shù)。在判定框320中繼續(xù),如果系統(tǒng)檢測(cè)到存在調(diào)試器,那么,系統(tǒng)在框330繼續(xù),否則系統(tǒng)跳到框340。這一步驟可以是操作系統(tǒng)對(duì)異常的初始處理的一部分,在此期間,如果存在附加調(diào)試器則操作系統(tǒng)將第一機(jī)會(huì)通知提供給附加調(diào)試器。在框330中繼續(xù),系統(tǒng)通知附加調(diào)試器給予調(diào)試器處理異常的第一選項(xiàng)。調(diào)試器可以允許用戶繼續(xù)執(zhí)行過(guò)去的異常或?qū)?zhí)行重定向到應(yīng)用程序代碼中的另一位置。可以存在其中系統(tǒng)通知調(diào)試器的多種情況。第一,操作系統(tǒng)可以給予要向調(diào)試器通知發(fā)生的異常的機(jī)會(huì)。第二,在調(diào)用運(yùn)行時(shí)的異常處理程序之后,在此處描述的第一機(jī)會(huì)通知回調(diào)之前,系統(tǒng)給予附加調(diào)試器機(jī)會(huì)。在判定框340中繼續(xù),如果異常通知系統(tǒng)檢測(cè)到與異常在其中發(fā)生的幀相關(guān)聯(lián)的運(yùn)行時(shí)異常處理程序,那么,異常通知系統(tǒng)在框350繼續(xù),否則異常通知系統(tǒng)完成并允許以傳統(tǒng)的方式處理該異常。可以在諸如微軟.NET CLR或Sim Java虛擬機(jī)(VM)等的運(yùn)行時(shí)內(nèi)運(yùn)行在此描述的系統(tǒng)。在使用運(yùn)行時(shí)的場(chǎng)合,運(yùn)行時(shí)通常對(duì)在發(fā)生異常時(shí)操作系統(tǒng)通知的異常處理程序進(jìn)行注冊(cè)。在框350中繼續(xù),系統(tǒng)檢測(cè)到一種類(lèi)型的異常。例如,系統(tǒng)可以將操作系統(tǒng)SEH代碼映射到包裝較低級(jí)操作系統(tǒng)提供的異常的運(yùn)行時(shí)提供的類(lèi)型。系統(tǒng)也可以檢測(cè)到可能發(fā)生的指示諸如由于空對(duì)象引用引起的異常等的特定異常類(lèi)型的各種運(yùn)行時(shí)條件。在框360中繼續(xù),系統(tǒng)標(biāo)識(shí)與異常相關(guān)聯(lián)的運(yùn)行時(shí)線程對(duì)象。運(yùn)行時(shí)可以提供存儲(chǔ)與由運(yùn)行時(shí)托管的每一線程有關(guān)的數(shù)據(jù)的對(duì)象,且運(yùn)行時(shí)可以從異常在其中發(fā)生的線程的堆棧幀中標(biāo)識(shí)適當(dāng)?shù)木€程對(duì)象。例如,運(yùn)行時(shí)可以檢查線程本地存儲(chǔ)(TLS)以便定位運(yùn)行時(shí)對(duì)象。在框370中繼續(xù),系統(tǒng)標(biāo)識(shí)與所標(biāo)識(shí)線程對(duì)象相關(guān)聯(lián)的應(yīng)用對(duì)象。系統(tǒng)可以通過(guò)應(yīng)用對(duì)象來(lái)提供跨越許多線程的提前異常通知。例如,微軟.NET定義表示應(yīng)用的隔離邊界的AppDomain對(duì)象。主存插件的應(yīng)用可以包括多個(gè)AppDomain,例如,主機(jī)有一個(gè) AppDomain,每一插件有一個(gè) AppDomain0在框380中繼續(xù),系統(tǒng)調(diào)用與所標(biāo)識(shí)的應(yīng)用對(duì)象相關(guān)聯(lián)的異常通知處理程序。例如,AppDomain類(lèi)可以包括用于接收異常通知的處理程序委托。注意,在任何正常的異常處理發(fā)生之前,系統(tǒng)將異常對(duì)象提供給異常通知處理程序,以使得處理程序可以在異常時(shí)間檢查應(yīng)用狀態(tài)。在框390中繼續(xù),系統(tǒng)執(zhí)行正常的執(zhí)行處理以便處理異常。例如,系統(tǒng)可以執(zhí)行在執(zhí)行的幀中標(biāo)識(shí)異常處理程序并展開(kāi)堆棧直到所標(biāo)識(shí)處理程序清除已分配的對(duì)象的兩遍異常處理。因而,系統(tǒng)提供傳統(tǒng)的異常處理之前被插入的通知,該通知允許各應(yīng)用接收原本難以接收和捕捉可能對(duì)稍后分析有用的診斷信息的異常的通知。在框390之后,這些步驟結(jié)束。在一些實(shí)施方式中,在程序是在調(diào)試器下運(yùn)行時(shí),異常通知系統(tǒng)如在此所描述地操作。然而,各調(diào)試器通常在任何程序代碼運(yùn)行之前將第一機(jī)會(huì)異常通知提供給調(diào)試器。 對(duì)于異常通知系統(tǒng)來(lái)說(shuō)也是這樣。調(diào)試器直接地從操作系統(tǒng)接收第一機(jī)會(huì)異常通知。如果調(diào)試器操作員選擇繼續(xù)程序執(zhí)行,那么,程序代碼運(yùn)行,且在此描述的系統(tǒng)檢測(cè)到異常、將通知提供給已注冊(cè)的程序處理程序并執(zhí)行正常的異常處理。如果調(diào)試器操作員選擇重定向執(zhí)行(例如,在一些調(diào)試器中是“%t Next Matement (設(shè)定下一語(yǔ)句)”)或截取異常,那么,系統(tǒng)可以不接收異常,且提前通知和正常的異常處理都不發(fā)生。在一些實(shí)施方式中,異常通知系統(tǒng)檢測(cè)被應(yīng)用到已注冊(cè)的處理程序的屬性,該屬性影響處理程序接收哪些異常。例如,微軟.NET準(zhǔn)備屬性可以指示處理程序被設(shè)計(jì)為在存儲(chǔ)器不足條件下正確操作以使得運(yùn)行時(shí)將存儲(chǔ)器不足異常提供給處理程序。在存儲(chǔ)器不足條件期間調(diào)用任何程序代碼是危險(xiǎn)的,且一些程序代碼采取特定步驟以便能夠正確地運(yùn)行。.NET框架也提供受限執(zhí)行區(qū)域(CER),受限執(zhí)行區(qū)域發(fā)信號(hào)通知運(yùn)行時(shí)為代碼塊預(yù)先分配資源并提前執(zhí)行任何JIT編譯以使得即使稍后資源稀缺該代碼塊也可以安全運(yùn)行。 因?yàn)殡y以處理存儲(chǔ)器不足條件,異常通知系統(tǒng)可以不將存儲(chǔ)器不足異常提供給不指示(例如,通過(guò)設(shè)置屬性)處理程序被設(shè)計(jì)為處理這樣的條件的該處理程序。系統(tǒng)也可以檢測(cè)其他屬性,諸如指示處理程序?qū)τ谥甘緭p壞或潛在損壞的程序狀態(tài)(另一難以處理的異常的類(lèi)別)的異常作好準(zhǔn)備的屬性。在一些實(shí)施方式中,異常通知系統(tǒng)避免異常循環(huán)。在通知處理程序引起異常時(shí)發(fā)生異常循環(huán)。在本情況中,在已注冊(cè)的通知函數(shù)中引起的任何異??梢詫?dǎo)致系統(tǒng)再次調(diào)用向其通知第二異常的函數(shù)。如果處理程序再次引起異常,那么,這一過(guò)程無(wú)限重復(fù),直到堆棧溢出或某種其他條件停止執(zhí)行。系統(tǒng)可以以兩種方式中的一種運(yùn)轉(zhuǎn)。第一,系統(tǒng)可以忽略循環(huán)以便鼓勵(lì)開(kāi)發(fā)者修復(fù)他們的代碼。開(kāi)發(fā)者將往往快速地發(fā)現(xiàn)這樣的循環(huán)并修復(fù)導(dǎo)致循環(huán)的問(wèn)題。第二,系統(tǒng)可以避免循環(huán)。例如,系統(tǒng)可以忽略在已注冊(cè)的處理程序內(nèi)引起的異常,或者可以終止引起異常的處理程序的執(zhí)行并繼續(xù)進(jìn)行正常的異常處理。在一些實(shí)施方式中,響應(yīng)于異常,異常通知系統(tǒng)允許已注冊(cè)的處理程序函數(shù)執(zhí)行除了記錄程序狀態(tài)和將信息記入日志之外的動(dòng)作。例如,系統(tǒng)可以允許處理程序返回停止執(zhí)行的值或調(diào)用影響隨后的執(zhí)行的函數(shù)。例如,處理程序可以卸載在其中發(fā)生異常的 AppDomain,使得該AppDomai被標(biāo)記為中止并在異常被處理之后被中止。作為另一示例,調(diào)用插件中的第三方代碼的主機(jī)可以通過(guò)重定向異常處理或標(biāo)記引起異常類(lèi)型的插件以使得宿主將來(lái)不加載這樣的插件來(lái)防止插件處理應(yīng)用想要處理的特定類(lèi)型的異常。在一些實(shí)施方式中,如果異常通知系統(tǒng)沒(méi)有找到在其上發(fā)生異常的AppDomain上的已注冊(cè)的處理程序,那么,系統(tǒng)查找另一 AppDomain。例如,系統(tǒng)可以將異常編組到堆棧上的下一區(qū)域,以便找到向其通知異常的AppDomain。如果異常到達(dá)另一 AppDomain,則異常通知系統(tǒng)通知AppDomain的通知回調(diào)(如果有的話)。這在其中在插件的AppDomain內(nèi)發(fā)生異常但主存應(yīng)用想要接收異常的通知的主存情況中可能是有用的。系統(tǒng)也可以提供對(duì)線程編組改變的通知以使得主存應(yīng)用可以檢測(cè)到其處理程序接收的異常是在不同的AppDomain 中導(dǎo)致的。以下是使用異常通知系統(tǒng)的示例。微軟SQL服務(wù)器(SQL)管理員管理在單個(gè)服務(wù)器進(jìn)程中運(yùn)行的不同的數(shù)據(jù)庫(kù)。不穩(wěn)定性的原因之一是不期望的異常。SQL允許管理員在本機(jī)異常被引起時(shí)執(zhí)行回調(diào)(通過(guò)_y開(kāi)關(guān))。這允許管理員為本機(jī)異常創(chuàng)建定制日志和上下文轉(zhuǎn)儲(chǔ)。然而,現(xiàn)今,對(duì)于托管異常,不能這樣做。在此描述的這一通知允許SQL借助于與SQL為本機(jī)異常提供的相同的第一機(jī)會(huì)回調(diào)功能為托管異常提供回調(diào)。在一些實(shí)施方式中,異常通知系統(tǒng)允許程序代碼注冊(cè)具體的類(lèi)型的異常,以使得已注冊(cè)的處理程序不接收不重要的或不感興趣的異常類(lèi)型。例如,程序可以對(duì)次要異常 (例如,打開(kāi)文件的故障)不感興趣但是可以對(duì)更嚴(yán)重的出錯(cuò)(例如,訪問(wèn)沖突或存儲(chǔ)器不足條件)感興趣。在一些實(shí)施方式中,異常通知系統(tǒng)允許程序開(kāi)啟和關(guān)閉處理程序的調(diào)用。許多應(yīng)用在某些時(shí)刻產(chǎn)生許多異常。程序可以不想要記錄所有這些異常,因此可以等待程序啟動(dòng)完成,然后,開(kāi)啟處理程序的調(diào)用。同樣地,程序可以對(duì)程序關(guān)閉期間發(fā)生的異常不感興趣, 且可以在開(kāi)始一關(guān)閉進(jìn)程之前關(guān)閉對(duì)處理程序的調(diào)用。從前述可見(jiàn),應(yīng)明白,在此已經(jīng)出于示出的目的描述了異常通知系統(tǒng)的具體實(shí)施方式
,但可以在不偏離本發(fā)明的精神和范圍的前提下做出各種修改。因此,除了受所附權(quán)利要求限制之外,本發(fā)明不受其他限制。
權(quán)利要求
1.一種用于提供對(duì)異常的通知的計(jì)算機(jī)實(shí)現(xiàn)的方法,所述方法包括 在應(yīng)用的執(zhí)行期間接收310對(duì)異常已經(jīng)被引起的通知;檢測(cè)340與在其中發(fā)生過(guò)所述異常的幀相關(guān)聯(lián)的運(yùn)行時(shí)異常處理程序; 標(biāo)識(shí)350與所述異常相關(guān)聯(lián)的運(yùn)行時(shí)線程對(duì)象; 標(biāo)識(shí)370與所標(biāo)識(shí)的線程對(duì)象相關(guān)聯(lián)的應(yīng)用對(duì)象; 調(diào)用380與所標(biāo)識(shí)的應(yīng)用對(duì)象相關(guān)聯(lián)的異常通知處理程序;以及執(zhí)行390正常的異常處理以便處理所述異常并清除所分配的對(duì)象, 其中前述各步驟是由至少一個(gè)處理器來(lái)執(zhí)行的。
2.如權(quán)利要求1所述的方法,其特征在于,接收對(duì)異常已經(jīng)被引起的通知包括調(diào)用操作系統(tǒng)提供的函數(shù)來(lái)引起軟件異常。
3.如權(quán)利要求1所述的方法,其特征在于,接收對(duì)異常已經(jīng)被引起的通知包括接收對(duì)由硬件生成的硬件異常的通知。
4.如權(quán)利要求1所述的方法,其特征在于,進(jìn)一步包括,在接收對(duì)異常已經(jīng)被引起的通知之后,檢測(cè)調(diào)試器是否被附連到所述應(yīng)用,且響應(yīng)于確定調(diào)試器被附連到所述應(yīng)用,通知所附連的調(diào)試器以便給予所述調(diào)試器處理所述異常的第一選項(xiàng)。
5.如權(quán)利要求1所述的方法,其特征在于,進(jìn)一步包括檢測(cè)與所述異常相關(guān)聯(lián)的類(lèi)型, 其中檢測(cè)類(lèi)型包括將操作系統(tǒng)提供的代碼映射到運(yùn)行時(shí)類(lèi)型。
6.如權(quán)利要求1所述的方法,其特征在于,進(jìn)一步包括檢測(cè)與所述異常相關(guān)聯(lián)的類(lèi)型并將所檢測(cè)的類(lèi)型對(duì)象提供給所述異常通知處理程序。
7.如權(quán)利要求1所述的方法,其特征在于,標(biāo)識(shí)運(yùn)行時(shí)線程對(duì)象包括從在其中發(fā)生過(guò)所述異常且存儲(chǔ)與由所述運(yùn)行時(shí)托管的所述線程有關(guān)的數(shù)據(jù)的所述線程的所述堆棧幀中標(biāo)識(shí)適當(dāng)?shù)木€程對(duì)象,且其中,標(biāo)識(shí)應(yīng)用對(duì)象包括標(biāo)識(shí)表示應(yīng)用的隔離邊界的應(yīng)用域?qū)ο蟆?br>
8.如權(quán)利要求1所述的方法,其特征在于,調(diào)用所述處理程序包括通過(guò)所述應(yīng)用對(duì)象的方法標(biāo)識(shí)先前注冊(cè)的處理程序。
9.如權(quán)利要求1所述的方法,其特征在于,調(diào)用所述處理程序在執(zhí)行修改與所述異常相關(guān)的應(yīng)用狀態(tài)的異常處理之前發(fā)生。
10.一個(gè)用于在用于處理異常的路徑外提供對(duì)所引起的異常的通知的計(jì)算機(jī)系統(tǒng),所述系統(tǒng)包括被配置為執(zhí)行軟件指令的處理器和存儲(chǔ)器;被配置為從應(yīng)用接收對(duì)處理程序進(jìn)行注冊(cè)的請(qǐng)求的處理程序注冊(cè)組件110,所述處理程序響應(yīng)于異常發(fā)生來(lái)接收由所述系統(tǒng)提供的提前通知;被配置為檢測(cè)在程序正在執(zhí)行時(shí)異常被引起的異常檢測(cè)組件120 ; 被配置為響應(yīng)于所檢測(cè)的異常來(lái)查找異常狀態(tài)并標(biāo)識(shí)與所述異常相關(guān)聯(lián)的應(yīng)用對(duì)象的對(duì)象發(fā)現(xiàn)組件130 ;被配置為調(diào)用一個(gè)或多個(gè)已注冊(cè)的應(yīng)用處理程序以便在異常處理發(fā)生之前向所述處理程序通知所檢測(cè)的異常的異常通知組件140 ;以及被配置為在所述已注冊(cè)的應(yīng)用處理程序已經(jīng)被通知之后執(zhí)行異常處理的異常處理組件 150。
11.如權(quán)利要求10所述的系統(tǒng),其特征在于,所述處理程序注冊(cè)組件還被配置為基于其中所述處理程序是一方法的類(lèi)來(lái)標(biāo)識(shí)所述處理程序。
12.如權(quán)利要求10所述的系統(tǒng),其特征在于,所述處理程序注冊(cè)組件還被配置為確定處理程序注冊(cè)函數(shù)的調(diào)用者的安全級(jí)別并且如果所述調(diào)用者低于閾值安全級(jí)別則拒絕登記。
13.如權(quán)利要求10所述的系統(tǒng),其特征在于,所述異常檢測(cè)組件還被配置為對(duì)在所述異常被引起時(shí)要由操作系統(tǒng)通知的運(yùn)行時(shí)處理程序函數(shù)進(jìn)行注冊(cè)。
14.如權(quán)利要求10所述的系統(tǒng),其特征在于,所述對(duì)象發(fā)現(xiàn)組件還被配置為在異常類(lèi)的分層結(jié)構(gòu)中確定所述異常的類(lèi)型。
15.如權(quán)利要求10所述的系統(tǒng),其特征在于,所述異常通知組件還被配置為將異常對(duì)象作為參數(shù)提供給所述已注冊(cè)的處理程序,所述處理程序可以通過(guò)所述作為參數(shù)的異常對(duì)象來(lái)檢索關(guān)于所述異常的原因的附加信息。
全文摘要
在此描述提供在異常處理代碼已經(jīng)運(yùn)行之前軟件異常已經(jīng)發(fā)生的提前通知的異常通知系統(tǒng)。異常通知系統(tǒng)從程序代碼接收注冊(cè)處理程序以便在異常發(fā)生時(shí)接收提前通知的注冊(cè)請(qǐng)求。在異常發(fā)生時(shí),該系統(tǒng)引起調(diào)用每一已注冊(cè)的處理程序的事件。在處理程序返回之后,該系統(tǒng)執(zhí)行正常的異常處理,以使得提前通知不改變現(xiàn)有的異常處理行為。異常通知系統(tǒng)允許程序在程序狀態(tài)已經(jīng)由異常處理修改之前檢查和記錄異常。程序代碼可以捕捉關(guān)于異常的原因的詳盡信息以便允許進(jìn)一步的離線分析。因而,異常通知系統(tǒng)允許開(kāi)發(fā)者通過(guò)接收關(guān)于程序代碼中的不期望條件的更多信息來(lái)改善他們的程序。
文檔編號(hào)G06F9/44GK102422261SQ201080020348
公開(kāi)日2012年4月18日 申請(qǐng)日期2010年4月30日 優(yōu)先權(quán)日2009年5月6日
發(fā)明者A·J·帕多, G·康納, J·C·施瓦茨, M·M·馬格魯?shù)? Y·林 申請(qǐng)人:微軟公司