.Net CLR異常簡析

楔子

前面一篇研究了下C++異常的,這篇來看下,CLR的異常內存模型,實際上都是一個模型,承繼自windows異常處理機制。不同的是,有VC編譯器(vcruntime.dll)接管的部分,被CLR裏面的函數ProcessCLRException接管了。
注意:這裏面省略了一部分不必要贅述的細節問題,版本號分別爲(CLR PreView 7和vcruntime 14.0)


C++異常棧

vcruntime140_1d.dll!__FrameHandler4::CxxCallCatchBlock
(jmp rdx)ntdll.dll!RcConsolidateFrames
ntdll.dll!RtlRestoreContext
ntdll.dll!RtlGuardRestoreContext	
ntdll.dll!RtlUnwindEx	
vcruntime140_1d.dll!__FrameHandler4::UnwindNestedFrames
vcruntime140_1d.dll!CatchIt
vcruntime140_1d.dll!FindHandler
vcruntime140_1d.dll!__InternalCxxFrameHandler
vcruntime140_1d.dll!__CxxFrameHandler4	
ntdll.dll!RtlpExecuteHandlerForException()	
ntdll.dll!RtlDispatchException
ntdll.dll!KiUserExceptionDispatch()
KernelBase.dll!RaiseException()
vcruntime140d.dll!_CxxThrowException
ConsoleApplication2.exe!main	

CLR異常棧

>	coreclr.dll!ProcessCLRException	C++
 	ntdll.dll!RtlpExecuteHandlerForException
 	ntdll.dll!RtlDispatchException
 	ntdll.dll!KiUserExceptionDispatch
 	KernelBase.dll!RaiseException
 	coreclr.dll!`RaiseTheExceptionInternalOnly'::`53'::__Body::Run
 	coreclr.dll!RaiseTheExceptionInternalOnly
 	coreclr.dll!IL_Throw
 	00007ffa6faf040c()

對比

CLR異常棧的地址00007ffa6faf040c()實際上就是C#的main函數入口。對比的是C異常棧的函數入口main。
其它的一一對應(C# ----C++):
1.IL_Throw-》_CxxThrowException
2.RaiseTheExceptionInternalOnly和RaiseTheExceptionInternalOnly以及RaiseException-》RaiseException()
3.KiUserExceptionDispatch-》KiUserExceptionDispatch()
4.RtlDispatchException-》RtlDispatchException
5.RtlpExecuteHandlerForException》RtlpExecuteHandlerForException
6.ProcessCLRException -》__CxxFrameHandler4

注意粗體部分對應的,這個地方開始,VC和CLR分道揚鑣了。各自實現了後面函數異常處理的實現。

結尾

這裏面實現包含了大量的細節,本文只取其中比較重要部分敘述下。

作者:江湖評談
版權:本作品採用「署名-非商業性使用-相同方式共享 4.0 國際」許可協議進行許可。
image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章