zoukankan      html  css  js  c++  java
  • CLR Exception 0xE0434F4D和0xE0434352的区别

    《根据《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"。

    至于为什么会变,还待研究,也希望其他同好告知。同时也希望告知还有没有其他区别。

  • 相关阅读:
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q100-Q103)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q97-Q99)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q94-Q96)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q91-Q93)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q88-Q90)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q85-Q87)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q81-Q84)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q77-Q80)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q73-Q76)
    Sharepoint学习笔记—习题系列--70-573习题解析 -(Q70-Q72)
  • 原文地址:https://www.cnblogs.com/yilang/p/12056406.html
Copyright © 2011-2022 走看看