标签:def The col read span tac str oftype sys
《根据《CLR Exception---E0434352》和《CLR Exception---E0434F4D》这两篇随笔,我们会发现,这两个异常太相似了,除了代码值不一样,其他几乎都一样。在windbg里调试dmp时,也会看到都叫它们CLR Exception。那他们有什么区别呢?这个问题值得研究研究。
我查了很多资料都没查明白。但是黄天不负有心人。在我搞其他问题时,让我窥得一线道道儿来。
首先上个实际的例子,在VS2013里新建一个c#控制台工程ConsoleApplication1,代码如下:
static void Main(string[] args) { throw new System.Exception(); return; }
工程配置如下:
编译好后,用Windbg加载运行
输入g运行,接着会抛出异常中断
我们可以看到
此时抛出的异常是CLR exception---code e0434352
输入kv,观察下栈
0:000> kv
# ChildEBP RetAddr Args to Child
00 00bcf214 7234ea5c e0434352 00000001 00000005 KERNELBASE!RaiseException+0x62 (FPO: [4,22,0])
01 00bcf2b0 7234f626 00000000 a4329156 00bcf3a0 clr!RaiseTheExceptionInternalOnly+0x230 (FPO: [SEH])
02 00bcf378 07550882 076023ac 076023a0 00bcf394 clr!IL_Throw+0x146 (FPO: [Non-Fpo])
WARNING: Frame IP not in any known module. Following frames may be wrong.
03 00bcf388 721af066 010184c0 00bcf3e8 721b2375 0x7550882
04 00bcf394 721b2375 00bcf430 00bcf3d8 7234e800 clr!CallDescrWorkerInternal+0x34
05 00bcf3e8 721bb3f5 00000000 076023a0 00bcf444 clr!CallDescrWorkerWithHandler+0x6b (FPO: [Non-Fpo])
06 00bcf45c 722c6d3f 00bcf538 a43297ae 071d4d5c clr!MethodDescCallSite::CallTargetWorker+0x16a (FPO: [Non-Fpo])
07 00bcf580 722c741a 00bcf5c4 00000000 a43295c2 clr!RunMain+0x1b3 (FPO: [Non-Fpo])
08 00bcf7ec 722c7347 00000000 a4329efe 00a30000 clr!Assembly::ExecuteMainMethod+0xf7 (FPO: [Non-Fpo])
09 00bcfcd0 722c74c8 a4329f06 00000000 00000000 clr!SystemDomain::ExecuteMainMethod+0x5ef (FPO: [Non-Fpo])
0a 00bcfd28 722c75ee a4329f46 00000000 723117c0 clr!ExecuteEXE+0x4c (FPO: [Non-Fpo])
0b 00bcfd68 723117e5 a4329f8a 00000000 723117c0 clr!_CorExeMainInternal+0xdc (FPO: [Non-Fpo])
0c 00bcfda4 7295fa84 047a2010 729f43f0 7295fa20 clr!_CorExeMain+0x4d (FPO: [Non-Fpo])
0d 00bcfddc 729ee80e 729f43f0 72950000 00bcfe04 mscoreei!_CorExeMain+0xd6 (FPO: [Non-Fpo])
0e 00bcfdec 729f43f8 729f43f0 74c00419 00db6000 MSCOREE!ShellShim__CorExeMain+0x9e (FPO: [Non-Fpo])
0f 00bcfdf4 74c00419 00db6000 74c00400 00bcfe60 MSCOREE!_CorExeMain_Exported+0x8 (FPO: [0,0,4])
10 00bcfe04 76f2662d 00db6000 ba7d08ea 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
11 00bcfe60 76f265fd ffffffff 76f451e3 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
12 00bcfe70 00000000 729f43f0 00db6000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
可以看到,当我们的代码throw异常时,调用了clr!IL_Throw--->clr!RaiseTheExceptionInternalOnly--->KERNELBASE!RaiseException
输入 uf clr!RaiseTheExceptionInternalOnly观察下RaiseException的调用过程和参数传递
0:000> uf clr!RaiseTheExceptionInternalOnly
...
7234e9f4 c785bcffffff524343e0 mov dword ptr [ebp-44h],0E0434352h
clr!RaiseTheExceptionInternalOnly+0x19c:
7234e9fe 8b85e0ffffff mov eax,dword ptr [ebp-20h]
7234ea04 8b4004 mov eax,dword ptr [eax+4]
7234ea07 a900000010 test eax,10000000h
7234ea0c 0f8556931600 jne clr!RaiseTheExceptionInternalOnly+0x1a9 (724b7d68) Branch
clr!RaiseTheExceptionInternalOnly+0x1db:
7234ea12 8d95c4ffffff lea edx,[ebp-3Ch]
7234ea18 6a3e push 3Eh
7234ea1a 59 pop ecx
7234ea1b e873feffff call clr!IsExceptionOfType (7234e893)
7234ea20 85c0 test eax,eax
7234ea22 0f858b931600 jne clr!RaiseTheExceptionInternalOnly+0x1ef (724b7db3) Branch
clr!RaiseTheExceptionInternalOnly+0x1ea:
7234ea28 3985c8ffffff cmp dword ptr [ebp-38h],eax
7234ea2e 0f857f931600 jne clr!RaiseTheExceptionInternalOnly+0x1ef (724b7db3) Branch
clr!RaiseTheExceptionInternalOnly+0x1fb:
7234ea34 803d34208e7200 cmp byte ptr [clr!g_StackProbingEnabled (728e2034)],0
7234ea3b 0f8586931600 jne clr!RaiseTheExceptionInternalOnly+0x204 (724b7dc7) Branch
clr!RaiseTheExceptionInternalOnly+0x218:
7234ea41 6a01 push 1
7234ea43 8d8d8cffffff lea ecx,[ebp-74h]
7234ea49 e8e736e6ff call clr!GCPreempNoDtor::Enter (721b2135)
7234ea4e 56 push esi
7234ea4f 53 push ebx
7234ea50 57 push edi
7234ea51 ffb5bcffffff push dword ptr [ebp-44h]
7234ea57 ff15e4628f72 call dword ptr [clr!_imp__RaiseException (728f62e4)]
...
可以看到clr!RaiseTheExceptionInternalOnly函数传给RaiseException的参数确实是0xE0434352。
现在,我们修改下工程配置,将Framework版本改为3.5,如下
然后编译,在Windbg加载运行,最后程序抛出异常中断
可以看到此时抛出了CLR exception---code e0434f4d
输入kv,看下栈
0:000> kv
# ChildEBP RetAddr Args to Child
00 006feb3c 791f7e04 e0434f4d 00000001 00000001 KERNELBASE!RaiseException+0x62 (FPO: [4,22,0])
01 006feb9c 792595d0 06d02cb0 00000000 00000000 mscorwks!RaiseTheExceptionInternalOnly+0x2a8 (FPO: [Non-Fpo])
02 006fec60 08fc00a5 06d02cb0 06d02ca0 006fec80 mscorwks!JIT_Throw+0xfc (FPO: [Non-Fpo])
WARNING: Frame IP not in any known module. Following frames may be wrong.
03 006fec70 79181b6c 00000003 006fec84 006fed00 0x8fc00a5
04 006fec80 79198603 006fed50 00000000 006fed20 mscorwks!CallDescrWorker+0x33
05 006fed00 791a06a3 006fed50 00000000 006fed20 mscorwks!CallDescrWorkerWithHandler+0xa3 (FPO: [Non-Fpo])
06 006fee40 791a06d6 06abc030 006fef0c 006feed8 mscorwks!MethodDesc::CallDescr+0x19c (FPO: [Non-Fpo])
07 006fee5c 791a06f4 06abc030 006fef0c 006feed8 mscorwks!MethodDesc::CallTargetWorker+0x1f (FPO: [Non-Fpo])
08 006fee74 7926090d 006feed8 1c0b468b 00000000 mscorwks!MethodDescCallSite::Call_RetArgSlot+0x1a (FPO: [Non-Fpo])
09 006fefd8 7926082d 06ab301c 00000001 006ff014 mscorwks!ClassLoader::RunMain+0x223 (FPO: [Non-Fpo])
0a 006ff240 79260d4a 00000000 1c0b5e43 00000001 mscorwks!Assembly::ExecuteMainMethod+0xa6 (FPO: [Non-Fpo])
0b 006ff710 79260f34 002f0000 00000000 1c0b5e33 mscorwks!SystemDomain::ExecuteMainMethod+0x45e (FPO: [Non-Fpo])
0c 006ff760 79260e64 002f0000 1c0b5efb 00000000 mscorwks!ExecuteEXE+0x59 (FPO: [Non-Fpo])
0d 006ff7a8 7295fa84 4635529f 729f43f0 7295fa20 mscorwks!_CorExeMain+0x15c (FPO: [Non-Fpo])
0e 006ff7e0 729ee80e 729f43f0 72950000 006ff808 mscoreei!_CorExeMain+0xd6 (FPO: [Non-Fpo])
0f 006ff7f0 729f43f8 729f43f0 74c00419 00438000 MSCOREE!ShellShim__CorExeMain+0x9e (FPO: [Non-Fpo])
10 006ff7f8 74c00419 00438000 74c00400 006ff864 MSCOREE!_CorExeMain_Exported+0x8 (FPO: [0,0,4])
11 006ff808 76f2662d 00438000 589054b8 00000000 KERNEL32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo])
12 006ff864 76f265fd ffffffff 76f451d5 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH])
13 006ff874 00000000 729f43f0 00438000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
可以看到,当我们的代码throw异常时,调用了mscorwks!JIT_Throw-->mscorwks!RaiseTheExceptionInternalOnly--->KERNELBASE!RaiseException
输入 uf mscorwks!RaiseTheExceptionInternalOnly观察下RaiseException的调用过程和参数传递
0:000> uf mscorwks!RaiseTheExceptionInternalOnly
...
791f7d7c bb4d4f43e0 mov ebx,0E0434F4Dh
mscorwks!RaiseTheExceptionInternalOnly+0x1db:
791f7d81 8b4704 mov eax,dword ptr [edi+4]
791f7d84 a900000010 test eax,10000000h
791f7d89 7425 je mscorwks!RaiseTheExceptionInternalOnly+0x210 (791f7db0) Branch
mscorwks!RaiseTheExceptionInternalOnly+0x1e5:
791f7d8b 8d4508 lea eax,[ebp+8]
791f7d8e 50 push eax
791f7d8f 6a43 push 43h
791f7d91 e8c5feffff call mscorwks!IsExceptionOfType (791f7c5b)
791f7d96 85c0 test eax,eax
791f7d98 7416 je mscorwks!RaiseTheExceptionInternalOnly+0x210 (791f7db0) Branch
mscorwks!RaiseTheExceptionInternalOnly+0x1f4:
791f7d9a 81677cfff7ffff and dword ptr [edi+7Ch],0FFFFF7FFh
791f7da1 8b470c mov eax,dword ptr [edi+0Ch]
791f7da4 8945cc mov dword ptr [ebp-34h],eax
791f7da7 83f8ff cmp eax,0FFFFFFFFh
791f7daa 0f8476851d00 je mscorwks!RaiseTheExceptionInternalOnly+0x206 (793d0326) Branch
mscorwks!RaiseTheExceptionInternalOnly+0x210:
791f7db0 8d4508 lea eax,[ebp+8]
791f7db3 50 push eax
791f7db4 6a3d push 3Dh
791f7db6 e8a0feffff call mscorwks!IsExceptionOfType (791f7c5b)
791f7dbb 85c0 test eax,eax
791f7dbd 0f8572851d00 jne mscorwks!RaiseTheExceptionInternalOnly+0x224 (793d0335) Branch
mscorwks!RaiseTheExceptionInternalOnly+0x21f:
791f7dc3 394510 cmp dword ptr [ebp+10h],eax
791f7dc6 0f8569851d00 jne mscorwks!RaiseTheExceptionInternalOnly+0x224 (793d0335) Branch
mscorwks!RaiseTheExceptionInternalOnly+0x232:
791f7dcc 897dd4 mov dword ptr [ebp-2Ch],edi
791f7dcf 8d45d4 lea eax,[ebp-2Ch]
791f7dd2 2d00c00000 sub eax,0C000h
791f7dd7 8b8ff4010000 mov ecx,dword ptr [edi+1F4h]
791f7ddd 894dc8 mov dword ptr [ebp-38h],ecx
791f7de0 3bc1 cmp eax,ecx
791f7de2 0f8260851d00 jb mscorwks!RaiseTheExceptionInternalOnly+0x24a (793d0348) Branch
mscorwks!RaiseTheExceptionInternalOnly+0x26b:
791f7de8 c745d001000000 mov dword ptr [ebp-30h],1
mscorwks!RaiseTheExceptionInternalOnly+0x254:
791f7def 8bcf mov ecx,edi
791f7df1 e80f20f9ff call mscorwks!Thread::EnablePreemptiveGC (79189e05)
791f7df6 56 push esi
791f7df7 ff75e4 push dword ptr [ebp-1Ch]
791f7dfa ff75e0 push dword ptr [ebp-20h]
791f7dfd 53 push ebx
791f7dfe ff1554121879 call dword ptr [mscorwks!_imp__RaiseException (79181254)]
...
可以看到mscorwks!RaiseTheExceptionInternalOnly函数传给RaiseException的参数确实是0xE0434F4D。
通过这两个对比,我们可以发现视乎CLR异常跟.net Framework版本有关,我又做了.net Framework 3.0/2.0,发现CLR异常是0xE0434F4D,而.net Framework 4.0/4.6/4.7/4.8版本的CLR异常是0xE0434352,同时我们发现0xE0434F4D是在mscorwks模块抛出,而0xE0434352是在clr模块抛出,结合《CLR调试时的sos.dll/clr.dll/mscorwks.dll/mscordacwks.dll等动态库的版本对应》一文,我们可以总结如下:
CLR Exception 0xE0434F4D和0xE0434352它们有一点区别是"CLR2.0版本是0xE0434F4D代码而在CLR4.0就已经改为0xE0434352"。
至于为什么会变,还待研究,也希望其他同好告知。同时也希望告知还有没有其他区别。
CLR Exception 0xE0434F4D和0xE0434352的区别
标签:def The col read span tac str oftype sys
原文地址:https://www.cnblogs.com/yilang/p/12056406.html