最初發表在QQ空間,全文參見 理解UnhandledExceptionFilter
UnhandledExceptionFilter,在一個windows平臺上的C/C++程序中,主線程的SEH框架會有2層,最外層是BaseProcessStart,裏面是mainCRTStartup,這意味着一般情況下,當有異常發生時,UnhandledExceptionFilter會被調用2次。
UEF首先會檢測當前進程的DebugPort,如果存在,則返回EXCEPTION_CONTINUE_SEARCH,繼續分發異常。這也是爲什麼,只有在調試情況下,用戶態異常纔有第2輪分發的機會。
下面,UEF會調用_BasepCurrentTopLevelFilter(如果存在),這個值是用SetUnhandledExceptionFilter設定的。參見 Windows平臺下的異常處理
然後,UEF中會檢測是否顯示GPF,如果不顯示,則UEF返回EXCEPTION_EXECUTE_HANDLER,通常也就是終止進程。
UEF接下來會顯示Error Box,要麼用戶選擇關閉進程,也還是如上面一樣,UEF返回EXCEPTION_EXECUTE_HANDLER,終止進程,要麼用戶就啓用了JIT,UEF返回EXCEPTION_CONTINUE_SEARCH,這樣纔會有調用外層UEF的機會。
在第一次的UEF調用中,如果啓用了JIT,則由於NtDebugActiveProcess函數的作用,當前的進程已經成爲了一個被調試的進程,所以第2次的UEF調用中檢測到當前進程是一個被調試的進程,直接返回了EXCEPTION_CONTINUE_SEARCH,這樣也導致了第2輪的異常分發,調試器會首先收到這一異常。
從上面的流程可以看出,用戶自定義的未處理異常過濾器即頂層異常過濾器被調用的條件是2個,1. 發生未處理的異常 2. 當前進程不在被調試
2011/05/04:
補充一個意外的發現,__report_gsfailure中UEF的特殊行爲